ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

多校联测20191009test

2019-10-09 21:56:16  阅读:244  来源: 互联网

标签:10 ch 20191009test int 多校 read 联测 权值 isdigit


题目:

1 文体两开花 1.1题目描述 众所周知,小G擅长文体两开花。 现在小G手中拿到了一棵树,这棵树的每个节点上都有一个非负整数权值vali。 为了展现自己深不可测的开花功底,小G会对这棵树进行一系列操作,具体表现为修改某个节点x 的权值。在每次修改之后,小G想要你告诉他,所有与节点x距离不超过2的所有节点的权值异或和是 多少。 1.2输入格式 从文件blossom.in中读入数据。 输入数据第一行包含两个正整数n,q,表示树的节点数以及修改/询问次数。 第一行n个空格隔开的正整数vali,表示每个点的权值。 接下来n~1行,每行两个正整数x,y,表示一条树边(x,y)。 接下来q行,每行两个整数x,v,表示将节点x的权值修改成v。 1.3输出格式 输出到文件blossom.out中。 为避免输出过量,记第i次询问的答案为ansi,你只需要输出∑(q)i=1ansi×i2对109+7取模的结果即可。 1.4样例1输入 5 3 1 2 3 4 5 1 2 1 3 2 4 2 5 3 6 4 7 5 8 1.5样例1输出 117 1.6样例1解释 3次询问对应的答案分别为5,1,12。 对于30%的数据,1≤n,q≤1000。 对于60%的数据,1≤n,q≤105。 对于100%的数据,1≤n,q≤106,1≤x,y≤n,0≤vali,v<230。   sol 模拟即可: 注意直接预处理出距离为2以内的异或值,改变的时候全部改一下即可 时间复杂度O(n+q) code:  
 1 #include <bits/stdc++.h>
 2 #pragma GCC optmize(3)
 3 #define int long long
 4 using namespace std;
 5 int ans;
 6 int n,q;
 7 inline int read(){
 8     int x=0,f=1;char ch=getchar();
 9     while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
10     while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
11     return x*f;
12 }
13 const int N=1001000,mod=1e9+7;
14 int to[N*2],head[N],Next[N*2],dep1[N],dep2[N],a[N],fa[N];
15 int cnt=0;
16 void add(int x,int y){to[++cnt]=y;Next[cnt]=head[x];head[x]=cnt;}
17 void dfs(int x,int ffa)
18 {
19     dep1[fa[x]]^=a[x];//预处理出与 x 同一距离根节点为1的异或值 
20     dep2[fa[ffa]]^=a[x];//预处理出与 ffa 同一距离根节点为1的异或值 
21     for (int i=head[x];i;i=Next[i])
22     {
23         int u=to[i];
24         if (u==ffa) continue;
25         fa[u]=x;//u 的父亲为 x 
26         dfs(u,x);
27     }
28     //cout<<"dep1[fa[x]]= "<<dep1[fa[x]]<<" dep2[fa[ffa]]= "<<dep2[fa[ffa]]<<" fa[x]= "<<fa[x]<<" x= "<<x<<" fa[ffa]= "<<fa[ffa]<<" ffa= "<<ffa<<" a[x]= "<<a[x]<<endl;
29 }
30 signed main()
31 {
32     //freopen("blossom.in" ,"r",stdin );
33     //freopen("blossom.out","w",stdout);
34     
35     n=read();q=read();
36     for (int i=1;i<=n;i++) a[i]=read();
37     for (int i=1;i< n;i++)
38     {
39         int x,y;
40         x=read();
41         y=read();
42         add(x,y);add(y,x);
43     }
44     dfs(1,0);
45     for (int i=1;i<=q;i++)
46     {
47         int x,v;
48         x=read();v=read();
49         //cout<<"dep1[fa[x]]= "<<dep1[fa[x]]<<" dep2[fa[fa[x]]]= "<<dep2[fa[fa[x]]]<<" fa[x]= "<<fa[x]<<" fa[fa[x]]= "<<fa[fa[x]]<<" a[x]= "<<a[x]<<" v= "<<v<<endl;
50         dep1[fa[x]]^=a[x]^v;//异或值改变 
51         dep2[fa[fa[x]]]^=a[x]^v;//同理 
52         a[x]=v;//更新a[x] 
53         
54         int anslin=dep1[x]^dep2[x];
55         if (fa[fa[x]]) anslin^=a[fa[fa[x]]];//若有祖辈 则继续异或 ,因为祖辈不能改变之前的值 
56         if (fa[x]) anslin^=a[fa[x]]^dep1[fa[x]];//若有父辈 则要加入父辈值 父辈可改变之前的值 
57         else anslin^=a[x];//如果没有父辈,则肯定也没有祖辈 直接异或本身 
58         ans+=1ll*anslin*i%mod*i;//边乘边模,减少复杂度 
59         ans%=mod;        
60 //        cout<<anslin<<endl;
61     }
62     printf("%lld\n",ans);
63     return 0;
64 }
65 /*
66 5 3
67 1 2 3 4 5
68 1 2
69 1 3
70 2 4
71 2 5
72 3 6
73 4 7
74 5 8
75 
76 */

但以上代码只有60分,会T掉4个点,如果你把快读改成一个更优的话,AC100

 如下快读

 1 inline char read() {
 2     static const int IN_LEN = 1000000;
 3     static char buf[IN_LEN], *s, *t;
 4     return (s == t ? t = (s = buf) + fread(buf, 1, IN_LEN, stdin), (s == t ? -1 : *s++) : *s++);
 5 }
 6 template<class T>
 7 inline void read(T &x) {
 8     static bool iosig;
 9     static char c;
10     for (iosig = false, c = read(); !isdigit(c); c = read()) {
11         if (c == '-') iosig = true;
12         if (c == -1) return;
13     }
14     for (x = 0; isdigit(c); c = read()) x = x * 10 + (c ^ '0');
15     if (iosig) x = -x;
16 }

 

考场上我是直接暴力枚举,使用了换根法,导致每次都跑了一遍dfs,一共q次,再加上O(n*q)的暴力枚举

导致我只拿了30分,其余全部TLE了,考场SB代码:

code:

 

  1 #include<bits/stdc++.h>
  2 #pragma GCC optimize(3)
  3 #define int long long
  4 const int mod=1e9+7;
  5 const int N=1e6+10; 
  6 using namespace std;
  7 int yzl;
  8 int n,q,w,cnt,fuck,vv;
  9 int a[N]; 
 10 int tot,ver[N],head[N],nxt[N];
 11 int dep[N],depp[N],ans[N];
 12 void inint(){
 13     freopen("blossom.in","r",stdin);
 14     freopen("blossom.out","w",stdout);
 15 }
 16 inline int read(){
 17     int x=0,f=1;char ch=getchar();
 18     while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
 19     while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
 20     return x*f;
 21 }
 22 void add(int x,int y){
 23     ++tot;
 24     ver[tot]=y;
 25     nxt[tot]=head[x];
 26     head[x]=tot;
 27 }
 28 void dfs(int x,int fa){
 29 //    dep[x]=0;
 30     depp[x]=depp[fa]+1;
 31     for(int i=head[x];i;i=nxt[i]){
 32         int y=ver[i];
 33         if(y!=fa){
 34         //    dep[y]=dep[x]+1;
 35             dfs(y,x);
 36             depp[y]=depp[x]+1;
 37             //cout<<"dep= "<<dep[y]<<endl;
 38         }
 39     }
 40 }
 41 void dfs2(int x,int fa){
 42     dep[x]=dep[fa]+1;
 43     for(int i=head[x];i;i=nxt[i]){
 44         int y=ver[i];
 45         if(y!=fa){
 46             
 47             dfs2(y,x);
 48             w=x;
 49             dep[y]=dep[x]+1;
 50         //    cout<<"x= "<<x<<" y= "<<y<<endl;
 51         }
 52     }
 53 }
 54 int lowbit(int x){
 55     return x&-x;
 56 }
 57 void change(int x,int v){
 58     while(x<=n){
 59         a[x]=v;
 60         x+=lowbit(x);
 61     }
 62 }
 63 signed main()
 64 {
 65     inint();
 66     n=read(),q=read();
 67     for(int i=1;i<=n;i++){
 68         a[i]=read();
 69     }
 70     for(int i=1;i<n;i++){
 71         int x,y;
 72         x=read(),y=read();
 73         add(x,y);
 74         add(y,x);
 75     }
 76     dfs2(1,0);
 77     cnt=0;
 78     while(q--){
 79         cnt++;
 80         fuck=0,vv=0;
 81         int x,v;
 82         x=read(),v=read();
 83         dfs(x,0);
 84         //change(x,v);
 85         a[x]=v;
 86         vv=a[x];
 87         for(int i=1;i<=n;i++){
 88             if(abs(depp[x]-depp[i])<=2&&abs(depp[x]-depp[i])!=0){
 89                 
 90                 ans[cnt]=vv^a[i];
 91                 vv=vv^a[i];
 92                 //cout<<"a[x]= "<<a[x]<<endl;
 93                 //fuck=v^a[i];
 94                 //cout<<"ans= "<<ans[cnt]<<" cnt= "<<cnt<<endl;
 95                 //cout<<"v= "<<v<<endl;
 96                 //cout<<"i= "<<i<<" a[i]= "<<a[i]<<" vv= "<<vv<<" ans[cnt]= "<<ans[cnt]<<endl; 
 97                 //cout<<"i= "<<i<<endl;
 98             }
 99         //cout<<"depp= "<<depp[i]-1<<" i= "<<i<<endl;
100     }
101     
102         //cout<<dep[x]<<endl;
103     }
104     for(int i=1;i<=cnt;i++){
105         yzl+=ans[i]*i*i;
106         //cout<<"ans[i]= "<<ans[i]<<endl;
107         //cout<<"yzl= "<<yzl<<endl;
108     }
109     printf("%lld\n",(yzl%mod));
110     return 0;
111 }
112 /*
113 5 3 
114 1 2 3 4 5 
115 1 2 
116 1 3 
117 2 4 
118 2 5 
119 3 6 
120 4 7 
121 5 8
122 
123 117
124 */

 

心得总结:尽管我现在还是弱鸡一枚连多校题只能开暴力(还是只有NOIP难度),得分现在加起来连50都没有,但是原来我可能连暴力都打不满,经过2个月的训练,代码能力也逐渐提升了。

有些神犇大佬们不屑于做的题目但他们可能会掉意轻心,比如(一些小细节),可能最后得分还不如最浅显的暴力。

最后还是那句话:只要坚持不懈,就一点会成功。无论结果如何,只要自己尽最大的努力,也不会有遗憾了。

 

 

       

标签:10,ch,20191009test,int,多校,read,联测,权值,isdigit
来源: https://www.cnblogs.com/nlyzl/p/11644589.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有