wannafly挑战赛14
第一次打wannafly。。觉得自己好菜啊。。。
题目描述
整天与整数打交道的小明希望知道这个三棱锥内、上整点的数目。
他觉得数量可能很多,所以答案需要对给定的 M 取模。
输入描述:
输入有 1 ≤ T ≤ 105
组数据。9
每组数据中,输入两个整数 0 ≤ K ≤ 10
+ 7, 1 ≤ M ≤ 109
+ 7,意义如题目描述。
输出描述:
对于每组数据,输出一个整数,为三棱锥内、上整点的数目对 M 取模。
输入
4 0 60 1 60 29 60 29 100007
输出
1 4 40 4960
签到题吧。对于这个三棱锥,除了x=0,y=0,z=0外的斜平面上,他有(k+1)列,由上往下数第i列包含i个点,于是我们斜平面上有点 $ sum^{k+1}_{i=1} \ i= \frac{(k+1)(k+2)}{2} $ 。因此给三棱锥等距地切出k个和斜平面平行的平面,因此三棱锥上的所有点分布在这(k+1)个平面上,于是从下往上数第i个平面上的点数为 $ \frac{(i)(i+1)}{2} $ 对其求和,即$ \sum^{k+1}_{i=1} \ \frac{(i)(i+1)}{2} = \frac{ \sum^{k+1}_{i=1} \ (i)(i+1)}{2} = \frac{ (k+1)(k+2)(k+3) }{6} $ 因此按照公式写答案2333.
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 #define clr(x) memset(x,0,sizeof(x)) 3 #define clr_1(x) memset(x,-1,sizeof(x)) 4 #define mod 1000000007 5 #define LL long long 6 #define INF 0x3f3f3f3f 7 using namespace std; 8 const int N=1e5+10; 9 int T; 10 LL ans,k,m,dt,a[4]; 11 int main() 12 { 13 ios::sync_with_stdio(false); 14 cin>>T; 15 while(T--) 16 { 17 cin>>k>>m; 18 ans=1; 19 for(int i=1;i<=3;i++) 20 a[i]=k+i; 21 for(int i=1;i<=3;i++) 22 if(a[i]%2==0) 23 { 24 a[i]/=2; 25 break; 26 } 27 for(int i=1;i<=3;i++) 28 if(a[i]%3==0) 29 { 30 a[i]/=3; 31 break; 32 } 33 ans=a[1]*a[2]%m*a[3]%m; 34 cout<<ans<<endl; 35 } 36 }
题目描述
每个名字旁边都记录着这位村民的声望值,而且有的村民还和别人同名。
随着时间的推移,因为没有村民死亡,这个名册变得十分大。
2. 给定名字前缀 pi 的所有人的声望值变化 di
3. 查询名字为 sj 村民们的声望值的和(因为会有重名的)
4. 查询名字前缀为 pj 的声望值的和
输入描述:
第一行为两个整数 0 ≤ N ≤ 105
,表示接下来有 N 个操作;i
接下来 N 行,每行输入一个操作,行首为一个整数 1 ≤ o
≤ 4,表示这一行的操作的种类,
2. 前缀修改声望,这一行的格式为 2 pi di,其中 |di| ≤ 103
3. 查询名字的声望和,这一行的格式为 3 sj
4. 查询前缀的声望和,这一行的格式为 4 pj
输出描述:
对于每一次询问操作,在一行里面输出答案。
输入
20 1 a -10 1 abcba -9 1 abcbacd 5 4 a 2 a 9 3 aadaa 3 abcbacd 4 a 3 a 2 a 10 3 a 2 a -2 2 d -8 1 ab -2 2 ab -7 1 aadaa -3 4 a 3 abcba 4 a 4 c
输出
-14 0 14 13 -1 9 11 1 11 0
给trie做类似线段树的tag标记。
我们维护五个量,分别是当前节点路径字符串的数量、声望和,当前节点为前缀字符串的数量、声望和,以及标记tag。对于所有操作,操作的时候访问到当前点有tag的时候就往后面的节点pushdown。操作一在插入基础上pushdown。操作二像线段树一样,如果当前前缀存在,我们修改路径上的所有节点的值,并在终点处留下加上声望值的tag。三四操作就在pushdown后查询当前点的前缀声望和和前缀声望和。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 #define clr(x) memset(x,0,sizeof(x)) 3 #define clr_1(x) memset(x,-1,sizeof(x)) 4 #define mod 1000000007 5 #define LL long long 6 #define INF 0x3f3f3f3f 7 using namespace std; 8 const int N=1e6+10; 9 const int type=26; 10 int T; 11 struct node 12 { 13 int next[type]; 14 LL tag,sum,num,presum,prenum; 15 }trie[N]; 16 int tot; 17 char s[N]; 18 int n,m; 19 LL d; 20 void init() 21 { 22 tot=0; 23 memset(&trie[0],0,sizeof(trie[0])); 24 return ; 25 } 26 int makenode() 27 { 28 ++tot; 29 memset(&trie[tot],0,sizeof(trie[tot])); 30 return tot; 31 } 32 void pushdown(int now) 33 { 34 int p; 35 if(trie[now].tag) 36 { 37 for(int i=0;i<type;i++) 38 { 39 p=trie[now].next[i]; 40 if(p) 41 { 42 trie[p].tag+=trie[now].tag; 43 trie[p].sum+=trie[p].num*trie[now].tag; 44 trie[p].presum+=trie[p].prenum*trie[now].tag; 45 } 46 } 47 trie[now].tag=0; 48 } 49 return ; 50 } 51 void add(char *s,LL d) 52 { 53 int now=0,p; 54 for(int i=0;s[i];i++) 55 { 56 p=s[i]-'a'; 57 if(!trie[now].next[p]) 58 trie[now].next[p]=makenode(); 59 now=trie[now].next[p]; 60 pushdown(now); 61 trie[now].presum+=d; 62 trie[now].prenum++; 63 } 64 trie[now].sum+=d; 65 trie[now].num++; 66 return ; 67 } 68 void change(char *s,LL d) 69 { 70 int now=0,p; 71 int i; 72 for(i=0;s[i];i++) 73 { 74 p=s[i]-'a'; 75 if(!trie[now].next[p]) 76 break; 77 now=trie[now].next[p]; 78 pushdown(now); 79 } 80 if(!s[i]) 81 { 82 trie[now].tag+=d; 83 int nowto=0; 84 for(i=0;s[i];i++) 85 { 86 p=s[i]-'a'; 87 nowto=trie[nowto].next[p]; 88 trie[nowto].presum+=trie[now].prenum*d; 89 } 90 trie[now].sum+=d*trie[now].num; 91 } 92 return ; 93 } 94 LL query(char *s) 95 { 96 int now=0,p; 97 int i; 98 for(i=0;s[i];i++) 99 { 100 p=s[i]-'a'; 101 if(!trie[now].next[p]) 102 break; 103 now=trie[now].next[p]; 104 pushdown(now); 105 } 106 if(s[i]) 107 return 0; 108 else 109 return trie[now].sum; 110 } 111 LL querypre(char *s) 112 { 113 int now=0,p; 114 int i; 115 for(i=0;s[i];i++) 116 { 117 p=s[i]-'a'; 118 if(!trie[now].next[p]) 119 break; 120 now=trie[now].next[p]; 121 pushdown(now); 122 } 123 if(s[i]) 124 return 0; 125 else 126 return trie[now].presum; 127 } 128 int main() 129 { 130 ios::sync_with_stdio(false); 131 cin>>n; 132 init(); 133 for(int i=1;i<=n;i++) 134 { 135 cin>>m; 136 if(m==1) 137 { 138 cin>>s>>d; 139 add(s,d); 140 } 141 else if(m==2) 142 { 143 cin>>s>>d; 144 change(s,d); 145 } 146 else if(m==3) 147 { 148 cin>>s; 149 cout<<query(s)<<endl; 150 } 151 else 152 { 153 cin>>s; 154 cout<<querypre(s)<<endl; 155 } 156 } 157 return 0; 158 }
题目描述
输入描述:
第一行是一个T≤20代表测试组数。每组测试的第一行包含两个正整数是n,m(n≤105
,m≤108
),接下来n−13
行每行包含三个正整数a b d,分别表示a结点和b结点之间的距离是d,a,b∈[1,n],1≤d≤10
。请注意每棵树的根节点都是1号结点,并且保证输入合法。
输出描述:
对于每组测试样例输出一个整数表示所有子树sub-beauty中不超过m的最大值。如果所有子树的sub-beauty都大于m,输出-1。
输入
3 3 4 1 2 1 1 3 2 3 4 1 2 3 1 3 2 4 6 1 2 2 2 3 5 3 4 2
输出
3 -1 6
我们一次dfs求出所有点的beauty,然后我们第二次dfs,并保存根到当前点的路径上的点的beauty。由于这个beauty是非递增的,因此我们直接查询大于等于当前点u的sum[u] m的值在路径bueauty的位置,然后+1即为相减后最靠近m的值了。由于我傻了没发现递增。。于是我写了一个权值线段树维护orz。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 #define clr(x) memset(x,0,sizeof(x)) 3 #define clr_1(x) memset(x,-1,sizeof(x)) 4 #define mod 1000000007 5 #define LL long long 6 #define INF 0x3f3f3f3f 7 #define pb(x) push_back(x) 8 #define mp(x,y) make_pair(x,y) 9 using namespace std; 10 const int N=1e5+10; 11 vector<pair<int,LL>> edge[N]; 12 LL sum[N],cnum[N],val[N]; 13 int n,T,u,v,nl; 14 LL m,value,ans; 15 struct node 16 { 17 int l,r,num; 18 }tree[N<<2]; 19 void init(int i,int l,int r) 20 { 21 tree[i]=(node){l,r}; 22 if(l==r) 23 return ; 24 int mid=(l+r)>>1; 25 init(i<<1,l,mid); 26 init(i<<1|1,mid+1,r); 27 return ; 28 } 29 void update(int i,int pos,int val) 30 { 31 if(tree[i].l==tree[i].r) 32 { 33 tree[i].num+=val; 34 return ; 35 } 36 int mid=(tree[i].l+tree[i].r)>>1; 37 if(mid>=pos) 38 update(i<<1,pos,val); 39 else 40 update(i<<1|1,pos,val); 41 tree[i].num+=val; 42 return ; 43 } 44 LL query(int i,int l,int r) 45 { 46 if(tree[i].num==0) 47 return -INF; 48 if(tree[i].l>=l && tree[i].r<=r) 49 { 50 if(tree[i].l==tree[i].r) 51 return val[tree[i].l]; 52 if(tree[i<<1|1].num) 53 return query(i<<1|1,l,r); 54 else return query(i<<1,l,r); 55 } 56 int mid=(tree[i].l+tree[i].r)>>1; 57 LL ans=-INF; 58 if(mid>=l) 59 ans=max(ans,query(i<<1,l,r)); 60 if(mid<r) 61 ans=max(ans,query(i<<1|1,l,r)); 62 return ans; 63 } 64 void dfs1(int u,int f) 65 { 66 cnum[u]=1; 67 sum[u]=0; 68 for(auto p:edge[u]) 69 { 70 if(p.first!=f) 71 { 72 dfs1(p.first,u); 73 cnum[u]+=cnum[p.first]; 74 sum[u]+=cnum[p.first]*p.second+sum[p.first]; 75 } 76 } 77 val[u]=sum[u]; 78 return ; 79 } 80 void dfs2(int u,int f) 81 { 82 ans=max(query(1,lower_bound(val+1,val+nl+1,sum[u])-val,upper_bound(val+1,val+nl+1,sum[u]+m)-1-val)-sum[u],ans); 83 update(1,lower_bound(val+1,val+nl+1,sum[u])-val,1); 84 for(auto p:edge[u]) 85 if(p.first!=f) 86 dfs2(p.first,u); 87 update(1,lower_bound(val+1,val+nl+1,sum[u])-val,-1); 88 return ; 89 } 90 int main() 91 { 92 ios::sync_with_stdio(false); 93 cin>>T; 94 while(T--) 95 { 96 cin>>n>>m; 97 for(int i=1;i<=n;i++) 98 edge[i].clear(); 99 for(int i=2;i<=n;i++) 100 { 101 cin>>u>>v>>value; 102 edge[u].pb(mp(v,value)); 103 edge[v].pb(mp(u,value)); 104 } 105 ans=-1; 106 dfs1(1,1); 107 sort(val+1,val+n+1); 108 nl=unique(val+1,val+n+1)-val-1; 109 init(1,1,nl); 110 dfs2(1,1); 111 cout<<ans<<endl; 112 } 113 return 0; 114 }
题目描述
给一个1-base数组{a},有N次操作,每次操作会使一个位置无效。一个区间的权值定义为这个区间里选出一些数的异或和的最大值。求在每次操作前,所有不包含无效位置的区间的权值的最大值。
输入描述:
第一行读入一个正整数(1 <= n <= 105)
第二行读入n个正整数,第i个表示a[i](0<= a[i] <= 109)
第三行读入n个正整数,第i个表示x[i]即第i次操作的位置,保证x[i]互不相同。
输出描述:
输出n行答案
输入
10 169 816 709 896 58 490 97 254 99 796 4 2 3 10 5 6 1 8 9 7
输出
1023 994 994 994 490 490 254 254 99 97
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 #define clr(x) memset(x,0,sizeof(x)) 3 #define clr_1(x) memset(x,-1,sizeof(x)) 4 #define mod 1000000007 5 #define LL long long 6 #define INF 0x3f3f3f3f 7 #define pb(x) push_back(x) 8 #define mp(x,y) make_pair(x,y) 9 using namespace std; 10 const int N=1e5+10; 11 const int type=32; 12 int fa[N]; 13 int Find(int x) 14 { 15 if(fa[x]!=x) 16 fa[x]=Find(fa[x]); 17 return fa[x]; 18 } 19 LL liner[N][type],ans[N],rans,p; 20 int n,a[N],x[N],vis[N]; 21 int t; 22 void Union(int x,int y) 23 { 24 int xx=Find(x); 25 int yy=Find(y); 26 LL p; 27 for(int i=type-1;i>=0;i--) 28 { 29 if(liner[xx][i]) 30 { 31 p=liner[xx][i]; 32 for(int j=type-1;j>=0;j--) 33 { 34 if(p>>j) 35 { 36 if(liner[yy][j]) 37 p^=liner[yy][j]; 38 else 39 { 40 liner[yy][j]=p; 41 break; 42 } 43 } 44 } 45 } 46 } 47 fa[xx]=yy; 48 return ; 49 } 50 void init(int n) 51 { 52 clr(liner); 53 LL p; 54 for(int i=1;i<=n;i++) 55 { 56 fa[i]=i; 57 vis[i]=0; 58 p=(LL)a[i]; 59 for(int j=type-1;j>=0;j--) 60 { 61 if(p>>j) 62 { 63 if(!liner[i][j]) 64 { 65 liner[i][j]=p; 66 break; 67 } 68 else 69 p=p^liner[i][j]; 70 } 71 } 72 } 73 return ; 74 } 75 int main() 76 { 77 scanf("%d",&n); 78 for(int i=1;i<=n;i++) 79 scanf("%d",a+i); 80 for(int i=1;i<=n;i++) 81 scanf("%d",x+i); 82 init(n); 83 rans=0; 84 for(int i=n;i>=1;i--) 85 { 86 vis[x[i]]=1; 87 if(vis[x[i]-1]) 88 Union(x[i]-1,x[i]); 89 if(vis[x[i]+1]) 90 Union(x[i]+1,x[i]); 91 t=Find(x[i]); 92 p=0; 93 for(int j=31;j>=0;j--) 94 if(liner[t][j]) 95 p=max(p^liner[t][j],p); 96 rans=max(rans,p); 97 ans[i]=rans; 98 } 99 for(int i=1;i<=n;i++) 100 printf("%lld\n",ans[i]); 101 return 0; 102 }