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

    假的div2 C题没事写什么公式被卡精度了,掉分了gg

    ---------------------------------------------------

    A....几个每个字符串预先给好一个代表的值,给n个字符串,求和。

    题解:手速题。

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<queue>
    #include<cstring>
    #include<map>
    #define ll long long
    #define INF 2000000000
    using namespace std;
    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;
    }
    
    map<string,int> mp;
    int n;
    ll ans=0;
    string st;
    
    int main()
    {
        n=read();mp["Tetrahedron"]=4;
        mp["Cube"]=6;
        mp["Octahedron"]=8;
        mp["Dodecahedron"]=12;
        mp["Icosahedron"]=20;
        for(int i=1;i<=n;i++)
            cin>>st,ans+=mp[st];
        cout<<ans;
        return 0;
    }

    B.有两种课,每种课都有很多节,每节课有一段时间l..r,你要从两种课中都选一节,使得中间的休息时间最长。

    题解:两边都分别记一下最小值,最大值。

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<queue>
    #include<cstring>
    #include<map>
    #define ll long long
    #define INF 2000000000
    using namespace std;
    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;
    }
    
    int mx1,mx2,mn1=INF,mn2=INF;
    int n,m,ans=0;
    
    int main()
    {
        n=read();
        for(int i=1;i<=n;i++)
        {
            int l=read();int r=read();
            mx1=max(mx1,l);mn1=min(mn1,r);
        }
        m=read();
        for(int i=1;i<=m;i++)
        {
            int l=read();int r=read();
            mx2=max(mx2,l);mn2=min(mn2,r);
        }
        ans=max(ans,max(mx1-mn2,mx2-mn1));
        cout<<ans;
        return 0;
    }

    C.有一个大小为n的粮仓,一开始是满的,每天都会运来m的粮食,但是不能超过大小上限,然后运来后会有不速之客来吃,第i天吃掉i的粮食,求第几天粮食被吃完了。

    n,m<=10^18

    正确解法:二分答案,等差数列求和

    我的错误解法:解一元二次方程,结果用了double被卡精度,FST了,改成long double 就过了.... 心累。

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<queue>
    #include<cstring>
    #include<map>
    #include<cmath>
    #define ll unsigned long long
    #define double long double
    #define INF 2000000000
    #define eps 1e-8
    using namespace std;
    inline ll read()
    {
        ll 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;
    }
    
    ll n,m,size;
    
    int main()
    {
        n=read();m=read();
        if(n<=m)cout<<n;
        else
        {
            double mm=sqrt((double)n*2.0-(double)m*2.00+0.25)-0.5;
            m+=(ll)ceil(mm);
            cout<<m;
        }
        return 0;
    }

    D.给定一个长度为n的括号序列,求特殊的括号子序列的数量。特殊的是指,前一半是(,后一半是)     n<=200000

    左边有n个左括号,右边有m个右括号,我们为了去重要求一定选最右的哪个左括号,这是侯答案数量是∑C(n,k-1)*C(m,k) k=1..min(n,m)

    然后我们会发现这个式子就等于C(n+m-1,m-1),所以预处理好阶乘和逆元,就可以算啦。

    复杂度O(n)

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<queue>
    #include<cstring>
    #include<map>
    #include<cmath>
    #define ll long long
    #define INF 2000000000
    #define mod 1000000007
    using namespace std;
    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;
    }
    
    int n;
    char s[200005];
    ll p[200005],l[200005];
    int num1=0,num2=0;
    ll ans=0;
    
    ll work(int n,int c)
    {
        return p[n]*l[c]%mod*l[n-c]%mod;
    }
    
    int main()
    {
        scanf("%s",s+1);n=strlen(s+1);
        p[0]=l[0]=l[1]=1;
        for(int i=1;i<=200000;i++)p[i]=p[i-1]*i%mod;
        for(int i=2;i<=200000;i++)l[i]=(mod-mod/i)*l[mod%i]%mod;
        for(int i=2;i<=200000;i++)l[i]=l[i]*l[i-1]%mod;
        for(int i=1;i<=n;i++)num2+=(s[i]==')');
        for(int i=1;i<=n;i++)
        {
            if(s[i]==')')num2--;
            else
            {num1++;ans=(ans+work(num1+num2-1,num2-1))%mod;}
        }
        cout<<ans;
        return 0;
    }

    E.给定一个1-n的全排列,一开始是1到n摆放。q个操作,每次交换一对数,然后要求交换后的逆序对数量。n<=200000,q<=50000 题目有4s

    1.分块+树状数组。复杂度应该是n^1.5*logn

    2.树状数组套平衡树.....(ditoly真的强,几下就切完了)复杂度nlog^2n

    分块 2308ms

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #define ll long long
    #define MAXN 200005
    #define MAXB 455
    using namespace std;
    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;
    }
    
    int n,m,size;
    ll ans=0;
    int c[MAXB][MAXN],s[MAXN],block[MAXN];
    
    void renew(int num,int x,int ad)
    {
        for(;x<=n;x+=x&(-x))
            c[num][x]+=ad;
    }
    
    int query(int num,int x)
    {
        int sum=0;
        for(;x;x-=x&(-x))
            sum+=c[num][x];
        return sum;
    }
    
    ll solve(int l,int r,int num)
    {
        if(l>r)return 0;
        int sum=0;
        if(block[l]==block[r])
        {
            for(register int i=l;i<=r;i++)sum+=(s[i]<num);
            return(ll)sum;
        }
        for(register int i=block[l]+1;i<block[r];i++)
            sum+=query(i,num);
        if(block[l-1]!=block[l])sum+=query(block[l],num);
        else for(register int i=l;block[i]==block[l]&&i<=r;i++)sum+=(s[i]<num);
        if(block[l]==block[r]) return (ll)sum;
        if(block[r+1]!=block[r])sum+=query(block[r],num);
        else for(register int i=r;block[i]==block[r]&&i>=l;i--)sum+=(s[i]<num);
        return(ll)sum;
    }
    
    int main()
    {
        n=read();m=read();size=sqrt(n);
        for(int i=1;i<=n;i++)block[i]=(i-1)/size+1;
        for(int i=1;i<=n;i++)s[i]=i,renew(block[i],i,1);
        for(register int i=1;i<=m;i++)
        {
            int u=read(),v=read();if(u>v)swap(u,v);
            if(u==v){printf("%lld
    ",ans);continue;}
            if(u!=v-1)
            {
                ans+=2*solve(u+1,v-1,s[v]);
                ans-=2*solve(u+1,v-1,s[u]);
            }
            renew(block[u],s[u],-1);renew(block[u],s[v],1);
            renew(block[v],s[v],-1);renew(block[v],s[u],1);
            swap(s[u],s[v]);
           // cout<<ans;
            if(s[u]>s[v])ans++;else ans--;
            printf("%lld
    ",ans);
        }
        return 0;
    }

    做法2以后补

  • 相关阅读:
    《百闻牌》
    unity插件开发:dos(cmd)命令输入窗口
    Unity插件开发:使用ScriptedImporter优化Lua文件导入
    崩坏3 渲染分析和PBR展示
    Unity插件开发:SerializedObject/SerializedProperty——查找引用的资源
    Unity插件开发:PrefabUtility(二)--Prefab实例批量Apply
    ml-agent v0.3 win10安装和实践
    Unity文件、文件引用、meta详解
    Unity开发:开启Unity项目中VS工程的属性面板
    Unity宏+RSP文件定义宏
  • 原文地址:https://www.cnblogs.com/FallDream/p/codeforces785.html
Copyright © 2011-2022 走看看