NOIP模拟测试23

这次考试又一次暴露了我很大的问题。

首先做的比较好的是这几次考试一分没挂,

但是,这也体现了更大的问题,那就是我的实力似乎也仅限于此了。

考试先拿满了暴力分(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 }
code

T3  我最想说的。

考场上一直以为是个数据结构题。

可是这是互质啊,为什么不想想数学呢?

这只是个简单的容斥啊。

想到容斥,一切就迎刃而解。

想不到呢?呵呵。

直接容斥即可。

O(msqrt(MAX{x[i]}))更新即可。

  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\n",ans);
 99     }
100     return 0;
101 }
code

加油

猜你喜欢

转载自www.cnblogs.com/hzoi-kx/p/11365943.html