DAY2 总结
知识的迁移,题目意思的分析
T1:互质数对

显然,对于在线的题目,我们应该认真的思考(如果计算过于麻烦,我们是不是可以通过增量来计算)
推导过程:
第二步到第三步:因为每一个d要满足|ax和ay,所以对于每一个μ来说,只有对于每一个ax加入进来的约数,会产生的只有(ay中是d倍数的个数,记录并计算就可)
注意数据范围 我们要统计约数,所以说数组的大小是数值范围而不是n,同样给我们以启示
如果说数论题目值域范围不大,就可以考虑用枚举约数的方式求解
#include <stdio.h> #include <algorithm> #include <cstring> #include <vector> using namespace std; const int maxn=2000020; typedef long long ll; int a[maxn]; bool c[maxn],st[maxn]; int prime[maxn],mob[maxn],cnt,f[maxn]; int n,q; ll ans=0; vector<int> v[maxn]; inline void init(int k) { mob[1]=1; for(int i=2;i<=k;i++) { if(!st[i]) { prime[cnt++]=i; mob[i]=-1; } for(int j=0;prime[j]*i<=k&&j<cnt;j++) { st[prime[j]*i]=true; if(i%prime[j]==0) break; mob[prime[j]*i]=-mob[i]; } } for(int i=1;i<=k;i++) if(mob[i]!=0)// ÓÅ»¯ for(int j=i;j<=k;j+=i) { v[j].push_back(i);//±£´æµÄ»¹ÊÇÔ¼Êý°¡ } return ; } int clar(int x) { int res=0; for(int i=0;i<v[x].size();i++) { res+=mob[v[x][i]]*f[v[x][i]]; } return res; } void ins(int x) { ans+=clar(x); for(int i=0;i<v[x].size();i++) { f[v[x][i]]++; } return; } void del(int x) { for(int i=0;i<v[x].size();i++) { f[v[x][i]]--; } ans-=clar(x); return; } int main() { // freopen("pair.in","r",stdin); // freopen("pair.out","w",stdout); scanf("%d%d",&n,&q); for(int i=1;i<=n;i++) scanf("%d",&a[i]); init(500020); while(q--) { int x;scanf("%d",&x); if(!c[x]) ins(a[x]); else del(a[x]); c[x]^=1; printf("%lld\n",ans); } return 0; }
T4 漫步校园:
- 矩阵复杂度 n^3->n^2logn
- 本质:状态i->二元关系(i,j)->状态j(阶段k表示的是矩阵加速的平方数)
- 三个要求:系数确定,乘方数量大,线性递推
- 观察到我们是(u,v)转移到(a,b)所以我们把状态拍扁
- (pos[u][v]->T.a[pos[u][v]][pos[a][b]]->pos[a][b]
- 乘方次数是n-1次
- 时间复杂度O(n^3log(乘方次数)
- 关于题目状态的抽象,总结成一句话,想想他是怎么来的
-
#include <stdio.h> #include <algorithm> #include <cstring> #include <cstdlib> #include <iostream> using namespace std; const int maxn=20; int pos[maxn][maxn],tot=0; int d,col[200]; double val[20][20]; int n,N; struct mar { int r,c; double a[17*17][17*17]; mar(){} mar(const int &p,const int &q)://ÖØÔØ¶¨Òå r(p),c(q) {memset(a,0,sizeof(a));} inline void init()//initµÄ×ÔÎÒÉèÖò»Òª¸úËæ±äÁ¿ { for(int i=1;i<=r;i++) a[i][i]=1.0; } inline mar operator * (const mar &s) const { mar res(r,s.c); for(int i=1;i<=r;i++) for(int k=1;k<=c;k++) for(int j=1;j<=s.c;j++) res.a[i][j]+=a[i][k]*s.a[k][j];// return res; } inline mar operator ^ (int k) const { mar temp(r,c),x = *this;//resÐèÒª´¢´æ´ð°¸£¬ËùÒÔÒªÖØÐ¶¨Òå temp.init(); while(k) { if(k&1) temp=temp*x; x=x*x; k>>=1; } return temp; } }A,T; int main() { freopen("walk.in","r",stdin); freopen("walk.ou","w",stdout); scanf("%d%d",&n,&N); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { scanf("%lf",&val[i][j]); pos[i][j]=++tot;a } A=mar(1,tot);T=mar(tot,tot); scanf("%d",&d); for(int i=1;i<=n;i++) scanf("%d",&col[i]); for(int a=1;a<=n;a++) for(int b=1;b<=n;b++) if(col[a]==col[b]) { for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) T.a[pos[i][j]][pos[a][b]]+=val[i][a]*val[j][b]; } double ans=0; A.a[1][1]=1; A = A * (T ^ ( N-1 ) ); for(int i=1;i<=tot;i++) ans+=A.a[1][i]; printf("%.9lf",ans); return 0; }
浙公网安备 33010602011771号