A.(polya计数+字符串匹配)
此题的难点在于确定置换的个数,由a[i+k]=a[i], e[i+k]=e[i]联想到KMP。
于是把原串和原串扩大两倍的目标串进行字符串匹配就能求出具体的置换。
这里的算法可以使用hash或者kmp。
然后套polya公式就行了。
#include#include #include #include #include #include #include #include #include #include #include #include #include
B.(平面图最小割转对偶图最短路)
BZOJ 狼抓兔子的简化版。
C.(待填坑)
D.(线段树和单调栈优化DP)
容易得到DP方程 dp[i]=dp[j]+max(val[j+1,i]) (pre[i]<=j<i).
复杂度为O(n^2logn) 需要优化。
方程右边的max()可以通过单调栈O(n)求出。复杂度O(n^2).
我们可以发现,假设此时扫到了k 对于单调栈里维护的两个连续的数 a[i]和a[j] (i>j) 那么max[[j+1,i], k]=a[i].
此时这些转移点的右边最大值部分都是一样的,那么我们只要求出这些转移点的dp部分最小值就行了。用一个线段树维护dp值,可以在logn的时间求出。
但是这样还是行不通,一个单调递减序列足以达到最坏复杂度。
可以再用一个线段树来维护min(dp[j]+max(...))。
复杂度O(nlogn).
#include#include #include #include #include #include #include #include #include #include
#include
E.(最短路变形)
这是个具有保护节点的最短路。 每个节点必须在到达他的所有前置节点之后才能访问它。
考虑在 堆优化dijkstra 判断入堆条件时 多加几个判断就ok了
# include# include # include # include # include # include # include # include
F.(离线+树状数组)
BZOJ HH的项链的变形。
G.(数论综合)
题目需要求sigma(lcm(i,n))-sigma(gcd(i,n))是否能被c整除。
结合欧拉函数和积性函数可以推出这两个式子,最后用大整数质因子分解算法可以算出答案。
#include#include #include #include #include const int TIME = 12;long long factor[100],fac_num[100];int count;int cmp(const void *a,const void *b){ long long temp; temp = *(long long*)a-*(long long *)b; if(temp==0) return 0; else if(temp<0) return -1; else return 1;}long long gcd(long long a,long long b){ if(b==0) return a; return gcd(b,a%b);}long long multi_mod(long long a,long long b,long long n){ long long res = 0; a%=n; for(;b;b>>=1) { if(b&1) res = (res+a)%n; a<<=1; a%=n; } return res;}long long multi_exp(long long a,long long b,long long n){ long long res = 1; for(;b;b>>=1) { if(b&1) res = multi_mod(res,a,n); a = multi_mod(a,a,n); } return res;}bool witness(long long a,long long n){ long long m,x,y; int i,j = 0; m = n-1; while(m%2==0) { j++; m>>=1; } x = multi_exp(a,m,n); for(i = 1;i<=j;i++) { y = multi_exp(x,2,n); if(y==1&&x!=1&&x!=n-1) return false; x = y; } if(y!=1) return false; return true;}bool Miller_Rabin(long long n,int times){ int i; long long a; if(n==1) return false; if(n==2) return true; if(n%2==0) return false; for(i = 1;i<=times;i++) { a = rand()%(n-2)+2; if(!witness(a,n)) return false; } return true;}long long pollard_rho(long long n){ long long i = 1, x = (long long)fabs(1.0*(rand() % (n - 1))) + 1, y, k, d, c; y = x, k = 2; do { c = (long long)fabs(1.0*(rand() % (n - 1))) + 1; } while (c == 0 || c == 2); do { i++; d = gcd(n + y - x, n); if (d != 1 && d != n) return d; if (i == k) y = x, k <<= 1; x = (multi_mod(x, x, n) + n - c) % n; } while (y != x); return n;}void get_factor(long long n){ long long temp; if(n==1) return ; if(Miller_Rabin(n,TIME)==true) { factor[count++] = n; return ; } temp = n; while(temp>=n) temp = pollard_rho(temp); get_factor(temp); get_factor(n/temp);}int main(){ long long n,c,temp1,temp2,temp3,keep; int count1,i,count2,T; srand(time(NULL)); scanf("%d",&T); while(T--) { scanf("%I64d%I64d",&n,&c); count = 0; get_factor(n); qsort(factor,count,sizeof(factor[0]),cmp); count1 = 0; count2 = 1; for(i = 1;i
H.(水题)
韦达定理。
# include# include # include # include # include # include # include # include
I.(水题)
结构体排序。
# include# include # include # include # include # include # include # include
J.(待填坑)