zoukankan      html  css  js  c++  java
  • Codeforces Round #532 (Div. 2)


    layout: post
    title: Codeforces Round #532 (Div. 2)
    author: "luowentaoaa"
    catalog: true
    tags:
    mathjax: true
    - codeforces


    传送门

    A. [A - Roman and Browser(水题)

    题意

    太水不想写

    B.Build a Contest (水题)

    题意

    给出一个n,m, 接下来吗每一时刻出现m个数,如果在某一时刻N种数字都出现过就输出'1'并同时把1-n种数字各删去一个

    题解

    很明显和每个数出现的最小值有关,如果出现数的最小值都大于等于1代表这n个数都出现过了,那么如何解决删去呢,如果每时刻都判断每个数都是否大于1就太浪费时间了,我们可以用个变量记录已经出现了多少个数,如果达到n再删去,这样复杂度并不会达到(n*m);

    同时也可以换方向,如果我不删去呢?

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    #define pp pair<int,int>
    const ll mod=998244353;
    const int maxn=1e6+50;
    const ll inf=0x3f3f3f3f3f3f3f3fLL;
    int gcd(int a,int b){while(b){int t=a%b;a=b;b=t;}return a;}
    int lcm(int a,int b){return a*b/gcd(a,b);}
    int a[maxn],mx[maxn];
    int flag[maxn];
    set<int>st;
    int num[maxn];
    double pi=acos(-1.0);
    void update(int now,int l,int r,int pos){
        if(l==r){
            mx[now]++;
            return;
        }
        int mid=(l+r)/2;
        if(pos<=mid)update(now<<1,l,mid,pos);
        else update(now<<1|1,mid+1,r,pos);
        mx[now]=min(mx[now<<1],mx[now<<1|1]);
    }
    int main()
    {
        std::ios::sync_with_stdio(false);
        std::cin.tie(0);
        std::cout.tie(0);
        int n,m;
        cin>>n>>m;
        int k=1;
        for(int i=1;i<=m;i++)cin>>a[i];
        for(int i=1;i<=m;i++){
            update(1,1,n,a[i]);
            if(mx[1]==k)k++,cout<<1;
            else cout<<0;
        }
    
        return 0;
    }
    //
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    #define pp pair<int,int>
    const ll mod=998244353;
    const int maxn=1e5+50;
    const ll inf=69;
    int gcd(int a,int b){while(b){int t=a%b;a=b;b=t;}return a;}
    int lcm(int a,int b){return a*b/gcd(a,b);}
    
    int a[maxn];
    int aa[maxn];
    
    int main()
    {
        std::ios::sync_with_stdio(false);
        std::cin.tie(0);
        std::cout.tie(0);
        int n,m;
        cin>>n>>m;
        int now=1;
        for(int i=1;i<=m;i++){
            int p;
            cin>>p;
            a[p]++;
            aa[a[p]]++;
            if(aa[now]>=n){
                cout<<1;now++;
            }
            else cout<<0;
        }
        return 0;
    }
    

    C.NN and the Optical Illusion (简单几何)

    一个圆均匀得被许多大小相等的小圆包围给你小圆个数和小圆半径 让你求出大圆半径.

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    #define pp pair<int,int>
    const ll mod=998244353;
    const int maxn=1e6+50;
    const ll inf=69;
    int gcd(int a,int b){while(b){int t=a%b;a=b;b=t;}return a;}
    int lcm(int a,int b){return a*b/gcd(a,b);}
    
    int sx,sy;
    struct node{
        int x,y;
        int id;
    }my[700];
    double pi=acos(-1.0);
    int main()
    {
       /* std::ios::sync_with_stdio(false);
        std::cin.tie(0);
        std::cout.tie(0);*/
      //  cin>>sx>>sy;
      //  for(int i=1;i<=666;i++)cin>>my[i];
        double n,r;
        cin>>n>>r;
        printf("%.7f
    ",sin(pi/n)*r/(1.0-sin(pi/n)));
        return 0;
    }
    

    D.Dasha and Chess (鸽笼定理)

    题意

    你操控白棋可以八连通走动,电脑操控黑棋会直接跳到任意没棋的格子,

    如果你操纵白棋走到和某个黑棋的行或者列你就赢了

    棋盘999*999,黑棋个数666个

    题解

    首先666/4=166.5

    先把棋子挪到中间,这时棋子就会分布在四个方位中,假设最分散的情况 比较多的三个方位中的棋子数肯定是大于或者等于666-166=500个的

    然后让棋子往最多棋子的那三个方向中的对角线的走去,因为棋子每次移动都向三个方向都移动一格,相当于同时把三个方向都扫了过去,而500.500到顶点只需要499步,所以肯定会有黑棋跑不掉

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    #define pp pair<int,int>
    const ll mod=998244353;
    const int maxn=1e6+50;
    const ll inf=69;
    int gcd(int a,int b){while(b){int t=a%b;a=b;b=t;}return a;}
    int lcm(int a,int b){return a*b/gcd(a,b);}
    
    int sx,sy;
    struct node{
        int x,y;
        int id;
    }my[700];
    int u,v,w;
    
    int vis[1005][1005];
    
    void go(int x,int y){
        sx+=x;sy+=y;
        if(vis[sx][sy])sx-=x;
        cout<<sx<<" "<<sy<<endl;
        cin>>u>>v>>w;
        if(u==-1)exit(0);
        vis[my[u].x][my[u].y]=0;
        vis[v][w]=1;
        my[u].x=v;my[u].y=w;
    }
    int main()
    {
        std::ios::sync_with_stdio(false);
        std::cin.tie(0);
        std::cout.tie(0);
        cin>>sx>>sy;
        for(int i=1;i<=666;i++)cin>>my[i].x>>my[i].y,vis[my[i].x][my[i].y]=1;
        int ok=1;
        while(sx<500)go(1,0);
        while(sx>500)go(-1,0);
        while(sy<500)go(0,1);
        while(sy>500)go(0,-1);
        int a=0,b=0,c=0,d=0;
        for(int i=1;i<=499;i++)
            for(int j=1;j<=499;j++)a+=vis[i][j];
        for(int i=1;i<=499;i++)
            for(int j=501;j<=999;j++)b+=vis[i][j];
        for(int i=501;i<=999;i++)
            for(int j=1;j<=499;j++)c+=vis[i][j];
        for(int i=501;i<=999;i++)
            for(int j=501;j<=999;j++)d+=vis[i][j];
        int aa=a+b+c,bb=a+b+d,cc=a+c+d,dd=c+b+d;
        int mx=max(max(aa,bb),max(cc,dd));
        if(aa==mx)while(true)go(-1,-1);
        if(bb==mx)while(true)go(-1,1);
        if(cc==mx)while(true)go(1,-1);
        else while(true)go(1,1);
        return 0;
    }
    

    E.Andrew and Taxi (二分答案+拓扑判环)

    题意

    给出一个有向图,让你把一些边反转需要花费费用Ci ,问你把这个图变成一个无环图需要的反转边的最大值最小是多少

    题意

    问最大最小值那必须是二分答案;

    首先可以二分答案,然后把大于答案的边 拿去进行拓扑判断是否有环,如果没环,那么这个答案就是合法的

    如果有环说明答案还要加,然后小于答案的边我们就把他们当成双向的就行了,因为题目要输出反转哪些边,所以我们可以记录拓扑序处理一下

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    #define pp pair<int,int>
    const ll mod=998244353;
    const int maxn=1e5+50;
    const ll inf=69;
    int gcd(int a,int b){while(b){int t=a%b;a=b;b=t;}return a;}
    int lcm(int a,int b){return a*b/gcd(a,b);}
    
    int n,m;
    
    struct node{
        int u,v;
        ll c;
    }my[maxn];
    vector<int>e[maxn];
    int in[maxn];
    int cnt[maxn];
    vector<int>anw;
    bool isok(ll mid){
        for(int i=1;i<=n;i++)e[i].clear();
        memset(in,0,sizeof(in));
        for(int i=1;i<=m;i++){
            if(my[i].c>mid)e[my[i].u].push_back(my[i].v),++in[my[i].v];
        }
        queue<int>p;
        int now=0;
        memset(cnt,0,sizeof(cnt));
        for(int i=1;i<=n;i++)if(in[i]==0)p.push(i),cnt[i]=++now;
        while(!p.empty()){
            int no=p.front();p.pop();
            for(int i=0;i<e[no].size();i++){
                int nex=e[no][i];
                in[nex]--;
                if(in[nex]==0){
                    p.push(nex);
                    cnt[nex]=++now;
                }
            }
        }
        for(int i=1;i<=n;i++)if(in[i])return false;
        anw.clear();
        for(int i=1;i<=m;i++){
            if(my[i].c<=mid&&cnt[my[i].u]>cnt[my[i].v]){
                anw.push_back(i);
            }
        }
        return true;
    }
    int main()
    {
        std::ios::sync_with_stdio(false);
        std::cin.tie(0);
        std::cout.tie(0);
    
        cin>>n>>m;
        ll l=0,r=0;
        for(int i=1;i<=m;i++){
            cin>>my[i].u>>my[i].v>>my[i].c;
            r=max(r,my[i].c);
        }
        ll ans=0;
        while(l<=r){
           ll mid=(l+r)/2;
           if(isok(mid)){
            ans=mid;
            r=mid-1;
           }
           else l=mid+1;
        }
        isok(ans);
        cout<<ans<<" "<<anw.size()<<"
    ";
        for(int i=0;i<anw.size();i++)cout<<anw[i]<<" ";
        return 0;
    }
    

    F.Ivan and Burgers (线性基)

    题意

    题意进行翻译就是求出区间的最大异或值了,因为n(nabc)==abc

    题解

    考虑贪心,对于每个位的贡献 如果大就留下来,如果同样大那就把比较后面的留下来 ,当然,需要离线处理区间

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    #define pp pair<int,int>
    const ll mod=998244353;
    const int maxn=5e5+50;
    const ll inf=69;
    int gcd(int a,int b){while(b){int t=a%b;a=b;b=t;}return a;}
    int lcm(int a,int b){return a*b/gcd(a,b);}
    const int maxbit=32;
    int n;
    
    int c[maxn];
    int q;
    struct node{
        int id;
        int l,r;
        bool operator <(const node &a)const{
            return this->r<a.r;
        }
    }Q[maxn];
    
    struct base{
        int num;
        int id;
    }my[maxbit];
    
    void ins(int num,int id){
        for(int i=31;i>=0;i--){
            if(num&(1<<i)){
                if(my[i].num==0){
                    my[i].id=id;
                    my[i].num=num;
                    break;
                }
                else if(my[i].id<id){
                    swap(my[i].id,id);
                    swap(my[i].num,num);
                }
                num^=my[i].num;
            }
        }
    }
    int ans[maxn];
    int main()
    {
        std::ios::sync_with_stdio(false);
        std::cin.tie(0);
        std::cout.tie(0);
        cin>>n;
        for(int i=1;i<=n;i++)cin>>c[i];
        cin>>q;
        for(int i=1;i<=q;i++){
            cin>>Q[i].l>>Q[i].r;Q[i].id=i;
        }
        sort(Q+1,Q+1+q);
        int now=1;
        for(int i=1;i<=q;i++){
            while(now<=Q[i].r)ins(c[now],now),now++;
            for(int j=31;j>=0;j--){
                if(my[j].id>=Q[i].l&&((ans[Q[i].id]^my[j].num)>ans[Q[i].id]))ans[Q[i].id]^=my[j].num;
            }
        }
        for(int i=1;i<=q;i++)cout<<ans[i]<<endl;
        return 0;
    }
    
  • 相关阅读:
    windows10下Mysql5.7安装指南
    SVN迁移Gitlab步骤
    java.lang.String中的replace方法到底替换了一个还是全部替换了。
    MongoDB升级导致启动失败
    阿里云CentOS7.3搭建多用户私有git服务器(从安装git开始)
    CentOS7.3编译安装Nginx设置开机启动
    关于使用Xshell远程连接启动tomcat导致图片不显示,报错Could not initialize class sun.awt.X11GraphicsEnvironment解决方案
    easyui报错“Cannot read poperty 'options' of undefined”问题解决方案之一
    Ubuntu18.04系统中vi键盘输入字符不匹配
    ux.form.field.TreePicker 扩展,修复火狐不能展开bug
  • 原文地址:https://www.cnblogs.com/luowentao/p/10335681.html
Copyright © 2011-2022 走看看