Codeforces Round#430(Div.2)
A. Kirill And The Game
x-y 乘k扫一遍是否在l-r范围内,用longlong保存
#include<bits/stdc++.h> using namespace std; long long l,r,x,y,q; double mmin,mmax; int main(){ cin>>l>>r>>x>>y; cin>>q; for(int i = x;i<=y;i++){ if(q*i>=l && q*i<=r){ cout<<"YES\n"; return 0; } } cout<<"NO\n"; return 0; }
B. Gleb And Pizza
单纯的模拟吧,本来以为会出点问题的
#include<bits/stdc++.h> using namespace std; double r,d,x[100100],y[100100],ra[100100]; int n; int cnt; double tocen; double dis(int x,int y){ return sqrt((pow(x,2)+pow(y,2))); } bool check(double dis,double rr){ if(dis-rr>=r-d && dis+rr<=r) return true; return false; } int main(){ scanf("%lf%lf",&r,&d); scanf("%d",&n); for(int i = 0;i<n;i++){ scanf("%lf%lf%lf",&x[i],&y[i],&ra[i]); } for(int i = 0;i<n;i++){ tocen = dis(x[i],y[i]); if(check(tocen,ra[i])) cnt++; } printf("%d\n",cnt); return 0; }
C. Ilya And The Tree
对当前访问的路径,每个节点x统计可以整除的数i,x/i的个数,如果这个数大于等于这条路径上访问过的节点数-1,那么可以通过将一个数替换为0使ans[x] = max(ans,i) ans = max(ans,x/i)
#include<bits/stdc++.h> using namespace std; const int maxn = 200200; struct EDGE{ int to,next; EDGE(){} EDGE(int a,int b){ to = a,next = b; } }e[maxn<<1]; int head[maxn],cnt,v[maxn],num[maxn],ans[maxn]; int gcd(int x,int y){return y?gcd(y,x%y):x;} void add_re(int a,int b){ e[++cnt] = EDGE(b,head[a]),head[a] = cnt; e[++cnt] = EDGE(a,head[b]),head[b] = cnt; } void dfs(int x,int fa,int d,int g){ ans[x] = g;int i; for(i = 1;i*i<num[x];i++) if(!(num[x]%i)){ if(++v[i] >= d) ans[x] = max(ans[x],i); if(++v[num[x]/i] >= d) ans[x] = max(ans[x],num[x]/i); } if(i*i == num[x] && ++v[i] >= d) ans[x] = max(ans[x],i); for(i = head[x];i;i = e[i].next){ int to = e[i].to; if(to != fa) dfs(to,x,d+1,gcd(num[x],g)); } for(i = 1;i*i<num[x];i++) if(!(num[x]%i)){ --v[i],--v[num[x]/i]; } if(i*i == num[x]) --v[i]; } int main(){ int st,ed,n; scanf("%d",&n); for(int i = 1;i<=n;i++) scanf("%d",&num[i]); for(int i = 1;i<n;i++) scanf("%d%d",&st,&ed),add_re(st,ed); dfs(1,0,0,0); for(int i = 1;i<=n;i++) printf("%d ",ans[i]); return 0; }
D. Vitya and Strange Lesson
对每个元素的异或可以简化为对目前所有query的异或而不用改变元素,建个线段树从高位查询
#include<bits/stdc++.h> using namespace std; const int maxn = 600000; inline int read(){ int x = 0,f= 1; char ch = getchar(); while(ch<'0' || ch>'9') {if(ch == '-') f=-1;ch = getchar();} while(ch>='0'&& ch<='9') {x = x*10+ch-'0';ch = getchar();} return x*f; } struct ST{ int x,l,r; }st[maxn<<2]; int s[25]; int n,m; void build(int x,int l,int r){ if((st[x].l = l) == (st[x].r = r)) return; int mid = (st[x].l+st[x].r)>>1; build(x<<1,l,mid);build(x<<1|1,mid+1,r); } void insert(int x,int k){ if(st[x].l == st[x].r) {st[x].x = 1;return;} int mid = st[x].l + st[x].r >> 1; insert(x<<1|(k>mid),k); st[x].x = st[x<<1].x+st[x<<1|1].x; } int query(int x,int k){ if(st[x].l == st[x].r) return 0; int y = x<<1|s[k]; if(st[y].x == st[y].r-st[y].l+1) return query(y^1,k-1)+(1<<k); else return query(y,k-1); } int main(){ n = read(); m = read(); build(1,0,524287); for(int i = 0;i<n;i++) insert(1,read()); while(m--){ int q = read(); for(int i = 18;i>=0;i--) if(q&(1<<i)) s[i]^=1; printf("%d\n",query(1,18)); } return 0; }