这次考试又一次暴露了我很大的问题。
首先做的比较好的是这几次考试一分没挂,
但是,这也体现了更大的问题,那就是我的实力似乎也仅限于此了。
考试先拿满了暴力分(100+0+50),然后看了看T2没看懂,打了个记忆化搜索,只有10分,此时只过了不到2个小时
没看懂题也就罢了,那真的是我菜,可是接下来,我没有再去深入思考T3,skyh考场上切掉的题,我连最基本的思路都没有,
可能这个题放在第一题,我就切了。
这不是一道难题,考完试我知道它是个容斥后,也自己推出来了。
可是T3只拿部分分的思维禁锢了我,我自己漫无目的地思考的结果,不过是一场空。
只是因为在考试后期,我没有了压力,自以为稳拿的150分已经够了。
真的。。。够吗?
考试的有效思考时间,与成绩正相关。
我可以允许自己爆零,但我不喜欢整场考试无所事事。
比你强的人,正常考试都在思考,而你却提前卸甲,这也就是之所以比你强的原因吧。
可能你有一个还算好看的名次,所以呢?
说实话,我记得建设城市那道题,还不算水,如果放在平时刷题,一个半小时我是不可能做出来的,但在考场上,我确实切掉了。
这就是,所谓压力下的动力吧。
一个人可以接受失败,但决不能自甘堕落。
你不够强大,这是事实。
但如果你一直畏难,就永远不能够强大。
你不是天才,但也不能自甘平庸。
你仍需历练
说考试
T1 DP过了
T2 题意转换->给定一个网格,询问从每个格子走到边界的所有路径中最大值中最小的。
跑最小生成树即可。
1 #include<bits/stdc++.h> 2 #define int long long 3 using namespace std; 4 const int root=1000005; 5 const int tmpx[5]={0,0,1,-1},tmpy[5]={1,-1,0,0}; 6 struct edge{ 7 int st,ed,val; 8 bool ok; 9 friend bool operator < (const edge a,const edge b) 10 { 11 return a.val<b.val; 12 } 13 }E[1000040]; 14 int cnt,head[1000040],nxt[1000040],to[1000040],pnt,f[1000040],w[1000040],n,m; 15 int d[1000040],h[304][305]; 16 int pt(int x,int y) 17 { 18 if(!x||!y||x==n+1||y==m+1)return root; 19 return (x-1)*m+y; 20 } 21 void Add(int u,int v,int val) 22 { 23 to[++pnt]=v; 24 nxt[pnt]=head[u]; 25 w[pnt]=val; 26 head[u]=pnt; 27 return ; 28 } 29 int find(int x) 30 { 31 if(f[x]==x)return x; 32 else return f[x]=find(f[x]); 33 } 34 void merge(int a,int b) 35 { 36 int fa=find(a),fb=find(b); 37 f[fa]=fb; 38 return ; 39 } 40 void dfs(int x,int fa) 41 { 42 for(int i=head[x];i;i=nxt[i]) 43 { 44 int y=to[i]; 45 if(y==fa)continue; 46 d[y]=max(d[x],w[i]); 47 dfs(y,x); 48 } 49 return ; 50 } 51 void BuildAndWork() 52 { 53 for(int i=1;i<=root;i++)f[i]=i; 54 for(int i=1;i<=n;i++) 55 for(int j=1;j<=m;j++) 56 { 57 for(int k=0;k<4;k++) 58 { 59 E[++cnt].st=pt(i,j); 60 E[cnt].ed=pt(i+tmpx[k],j+tmpy[k]); 61 E[cnt].val=max(h[i][j],h[i+tmpx[k]][j+tmpy[k]]); 62 } 63 } 64 sort(E+1,E+cnt+1); 65 for(int i=1;i<=cnt;i++) 66 { 67 int a=E[i].st,b=E[i].ed; 68 if(find(a)==find(b))continue; 69 Add(a,b,E[i].val);Add(b,a,E[i].val); 70 merge(a,b); 71 } 72 dfs(root,0); 73 } 74 signed main() 75 { 76 scanf("%lld%lld",&n,&m); 77 for(int i=1;i<=n;i++) 78 for(int j=1;j<=m;j++) 79 scanf("%lld",&h[i][j]); 80 BuildAndWork(); 81 int p=0; 82 for(int i=1;i<=n;i++) 83 { 84 for(int j=1;j<=m;j++) 85 { 86 int now=d[++p]; 87 printf("%lld ",now-h[i][j]); 88 } 89 puts(""); 90 } 91 return 0; 92 }
T3 我最想说的。
考场上一直以为是个数据结构题。
可是这是互质啊,为什么不想想数学呢?
这只是个简单的容斥啊。
想到容斥,一切就迎刃而解。
想不到呢?呵呵。
直接容斥即可。
$O(msqrt{max{x}})$更新即可。
1 #include<bits/stdc++.h> 2 #define MAXN 500005 3 #define cri const rigister int 4 using namespace std; 5 int t[MAXN],firprime[MAXN]; 6 int prime[MAXN],x[MAXN],val[MAXN],bin[MAXN],bitnum[MAXN]; 7 bool vst[MAXN]; 8 int lm[10]; 9 int kx; 10 void pre() 11 { 12 for(register int i=2;i<=500000;i++) 13 { 14 if(!firprime[i]) 15 prime[++prime[0]]=i,firprime[i]=i; 16 for(register int j=1;j<=prime[0]&&i*prime[j]<=500000;j++) 17 { 18 firprime[i*prime[j]]=prime[j]; 19 if(!(i%prime[j]))break; 20 } 21 } 22 return ; 23 } 24 void Get(register int x) 25 { 26 lm[0]=0; 27 while(x!=1) 28 { 29 register int now=firprime[x]; 30 lm[++lm[0]]=now; 31 while(x%now==0)x/=now; 32 } 33 return ; 34 } 35 int main() 36 { 37 pre(); 38 int n,m,siz=0; 39 long long ans=0; 40 val[0]=1; 41 for(int i=1;i<=7;i++)bin[1<<(i-1)]=i; 42 for(int i=1;i<=(1<<7-1);i++) 43 { 44 int num=0,st=i; 45 while(st)st-=st&-st,++num; 46 bitnum[i]=num; 47 } 48 scanf("%d%d",&n,&m); 49 for(int i=1;i<=n;i++) 50 scanf("%d",&x[i]); 51 while(m--) 52 { 53 int opt; 54 scanf("%d",&opt); 55 if(!vst[opt]) 56 { 57 Get(x[opt]); 58 kx=siz; 59 for(register int i=1;i<=(1<<lm[0])-1;i++) 60 { 61 val[i]=val[i^(i&-i)]*lm[bin[i&-i]]; 62 if(bitnum[i]&1)kx-=t[val[i]]; 63 else kx+=t[val[i]]; 64 } 65 vst[opt]=1; 66 int sx=sqrt(x[opt]); 67 for(register int i=2;i<=sx;i++) 68 if(x[opt]%i==0) 69 { 70 if(i*i==x[opt])t[i]++; 71 else t[i]++,t[x[opt]/i]++; 72 } 73 t[x[opt]]++; 74 siz++; 75 ans+=kx; 76 } 77 else 78 { 79 Get(x[opt]); 80 vst[opt]=0; 81 int sx=sqrt(x[opt]); 82 for(register int i=2;i<=sx;i++) 83 if(x[opt]%i==0) 84 { 85 if(i*i==x[opt])t[i]--; 86 else t[i]--,t[x[opt]/i]--; 87 } 88 t[x[opt]]--;siz--; 89 kx=siz; 90 for(register int i=1;i<=(1<<lm[0])-1;i++) 91 { 92 val[i]=val[i^(i&-i)]*lm[bin[i&-i]]; 93 if(bitnum[i]&1)kx-=t[val[i]]; 94 else kx+=t[val[i]]; 95 } 96 ans-=kx; 97 } 98 printf("%lld ",ans); 99 } 100 return 0; 101 }
加油