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;
}

 

posted @ 2017-08-30 19:35  Invisible_full_moon  阅读(110)  评论(0编辑  收藏  举报