• 2020 wannafly camp day1


    ------------恢复内容开始------------

    7-1 1A. 期望逆序对

    对每一对按期望排序即可(猜出来的,很好证明)

    #include <iostream>
    #include <map>
    #include <algorithm>
    #include <string.h>
    using namespace std;
    const int maxn=5e3+10;
    typedef long long ll;
    const int mod=998244353;
    ll len[maxn];
    ll inv2;
    ll qp(ll a,ll b,ll mod)
    {
        ll ans=1;
        while(b)
        {
            if(b&1)
                ans=(ans*a)%mod;
            a=(a*a)%mod;
            b>>=1;
        }
        return ans;
    }
    ll J(ll l1,ll r1,ll l2,ll r2,int i,int j)
    {
        ll ans=0;
        if(r1>r2)
        {
            ans=(r1-r2)*(r2-l2+1)%mod;
        }
        if(l2<l1)
        {
            ans=(ans+(l1-l2)*(r1-l1+1))%mod;
        }
    //    ans=(ans-max(0ll,l1-l2)*max(0ll,r1-r2)+mod)%mod;
        
        ll shang=min(r1,r2),xia=max(l1,l2);
        ll l=shang-xia+1;
        if(shang>xia)
        {
            ans=((ans+(l*l-l)%mod*inv2)%mod+mod)%mod;
        }
        return ((ans*len[i])%mod*len[j])%mod;
    }
    typedef pair<ll, ll> P;
    P a[maxn];
    bool cmp(P a1,P a2)
    {
        if(a1.first+a1.second<a2.first+a2.second)
            return 1;
        else
            return 0;
    }
    ll n;
    int main()
    {
        inv2=qp(2, mod-2, mod);
    //    cout<<(3*qp(8, mod-2, mod))%mod;
        scanf("%lld",&n);
        for(ll i=0;i<n;i++)
            scanf("%lld%lld",&a[i].first,&a[i].second);
    //        cin>>a[i].first>>a[i].second;
        sort(a, a+n, cmp);
        
        for(int i=0;i<n;i++)
        {
            len[i]=qp(a[i].second-a[i].first+1, mod-2, mod);
        }
        
        ll ans=0;
        for(ll i=0;i<n;i++){
            for(ll j=i+1;j<n;j++)
            {
                ll t=J(a[i].first, a[i].second, a[j].first, a[j].second,i,j);
    //            cout<<a[i].first<<a[i].second<<a[j].first<<a[j].second<<" "<<t<<endl;
                ans=(ans+t)%mod;
            }
        }
        printf("%lld
    ",ans);
    }

    7-2 1B. 密码学

    签到

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    char s[1002][1002];
    struct hh{
        int x,y;
    }a[2001];
    int n,m;
    bool daxie(char x){
        if(x >= 'A' && x <= 'Z') return true;
        else return false;
    } 
    char zhuan(char a,char b){
        int x,y;
        if(daxie(a)) x = a - 'A' + 26;
        else x = a - 'a';
        if(daxie(b)) y = b - 'A' + 26;
        else y = b - 'a';
        int c = (y - x + 52) % 52;
        if(c <= 25) c += 'a';
        else c += 'A' - 26;
        return (char)c;
    }
    
    void calc(int a,int b){
        char s2[1003];
        int cnt = 0,n1 = strlen(s[a]),m1 = strlen(s[b]);
        if(n1 < m1)
            while(cnt < m1){
                for(int i = 0;i < n1;i ++)
                    s2[i + cnt] = s[a][i];
                cnt += n1;
            }
        else strcpy(s2,s[a]);
        for(int i = 0;i < m1;i ++) s[b][i] = zhuan(s2[i],s[b][i]);
        return;
    }
    
    void solve(){
        cin >> n >> m;
        for(int i = 1;i <= m;i ++) scanf("%d%d",&a[i].x,&a[i].y);
        for(int i = 1;i <= n;i ++) scanf("%s",s[i]);
        for(int i = m;i >= 1;i --) calc(a[i].x,a[i].y);
        for(int i = 1;i <= n;i ++) printf("%s
    ",s[i]);
        return;
    }
    
    int main(){
        solve();
        return 0;
    }

     7-3 1C. 染色图

    首先应该是均摊颜色不难猜出,后来推公式有点烦,把n%i拆成n-n/i*i就行了,后来就分块就可以

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<set>
    #include<vector>
    #include<bitset>
    #include <string.h>
    #include <stack>
    using namespace std;
    #define ls rt<<1
    #define rs rt<<1|1
    typedef long long ll;
    const ll maxn = 998244353;
    const int mod=998244353;
    typedef pair<double, double> P;
    typedef long long ll;
    ll qp(ll a,ll b,ll mod)
    {
        ll ans=1;
        while(b)
        {
            if(b&1)
                ans=(ans*a)%mod;
            a=(a*a)%mod;
            b>>=1;
        }
        return ans;
    }
    ll J(ll L,ll R,ll k)//k/i
    {
        //n*k- xigema i*(k/i)x;
        ll ans=0;
        for(ll l=L,r=0;l<=R;l++)
        {
            if(k/l)
                r=min(R,k/(k/l));
            else
                r=R;
            ans=(ans+(k/l)*(r-l+1))%mod;
            l=r;
        }
        return ans;
    }
    ll J2(ll L,ll R,ll k)//k/i*i
    {
        //n*k- xigema i*(k/i)x;
        ll ans=0;
        for(ll l=L,r=0;l<=R;l++)
        {
            if(k/l)
                r=min(R,k/(k/l));
            else
                r=R;
            ans=((k/l)*(((r-l+1)*(l+r)/2)%mod)+ans)%mod;
            l=r;
        }
        return ans;
    }
    ll J3(ll L,ll R,ll k)//k/i*(k/i)*i
    {
        //n*k- xigema i*(k/i)x;
        ll ans=0;
        for(ll l=L,r=0;l<=R;l++)
        {
            if(k/l)
                r=min(R,k/(k/l));
            else
                r=R;
            ans=(ans+((k/l)*(k/l)%mod)*(((r-l+1)*(l+r)/2)%mod))%mod;
            l=r;
        }
        return ans;
    }
    int main()
    {
        int T;
        cin>>T;
        while(T--)
        {
            ll l,r,k;
            cin>>k>>l>>r;
            ll ans2=(((k*k%mod-k)*(r-l+1)%mod-2*J(l, r, k)*k+J3(l, r, k)+J2(l, r, k))%mod+mod)%mod;
            cout<<(ans2*qp(2, mod-2, mod))%mod<<endl;
        }
    }

     7-5 1E. 树与路径

    这道题我觉得还是很神奇的,这题虽然题干和其他换根的题很像,但是其实是很难想的。现在从原始思路出发,要求出所有点为根时候的答案,必然要先求一个答案,然后求转移。转移的时候就非常巧妙了,通过列式子可以得出对于一条边的时候,你变化的答案,其实仅仅与这个点与顶点的距离有关,所以就是说是与当前深度与顶点的差值是有关系的。所以说,把当前深度和叠加的顶点深度开一个pair,算一下这个,转移有了,然后dfs求答案。这题换根题求转移的必然的,只是不太好找这个规律。

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<set>
    #include<vector>
    #include<bitset>
    #include <string.h>
    #include <stack>
    using namespace std;
    #define ls rt<<1
    #define rs rt<<1|1
    typedef long long ll;
    const int maxn = 3e5+1000;
    typedef pair<ll, ll> P;
    P b[maxn],flag[maxn];
    vector<int> G[maxn];
    int F[maxn][20];
    int used[maxn],deep[maxn];
    ll ans[maxn];
    void J(ll x)
    {
        if(x<0||x>maxn)
            while(1);
    }
    void dfs(int x)
    {
        if(x<0||x>maxn)
        {
            while(1);
        }
        used[x]=1;
        for(int i=0;i<G[x].size();i++)
        {
            int v=G[x][i];
            J(v);
            if(used[v]==0)
            {
                deep[v]=deep[x]+1;
                F[v][0]=x;
                for(int i=1;i<20;i++)
                {
                    F[v][i]=F[F[v][i-1]][i-1];
                }
                dfs(v);
            }
        }
    }
    int count2=0;
    void dfs2(int x)
    {
        count2++;
        if(count2>=maxn)
            while(1);
            
        if(x<0||x>maxn)
        {
            while(1);
        }
        used[x]=1;
        
        b[x].first=flag[x].first;
        b[x].second=flag[x].second;
        for(int i=0;i<G[x].size();i++)
        {
            
            int v=G[x][i];
            J(v);
            if(used[v]==0){
                dfs2(v);
                b[x].first+=b[v].first;
                b[x].second+=b[v].second;
            }
        }
    }
    void dfs3(int x,ll ans_t)
    {
        J(x);
        used[x]=1;
        
        ans_t+=b[x].first*deep[x]+b[x].second;
        ans[x]=ans_t;
        for(int i=0;i<G[x].size();i++)
        {
            int v=G[x][i];
            J(v);
            if(used[v]==0)
                dfs3(v,ans_t);
        }
    }
    int lca(int t1,int t2)
    {
        if(deep[t1]<deep[t2])
            swap(t1,t2);
        for(int i=19;i>=0;i--)
        {
            J(t1);
            J(t2);
            if(deep[t1]-(1<<i)>=deep[t2])
            {
                
                t1=F[t1][i];
            }
        }
        if(t1==t2)
            return t2;
        for(int i=19;i>=0;i--)
        {
            J(t1);
            J(t2);
            if(F[t1][i]!=F[t2][i])
            {
                t1=F[t1][i];
                t2=F[t2][i];
            }
        }
        t1=F[t1][0];
        J(t1);
        return t1;
    }
    int main()
    {
        deep[1]=1;
        int n,m;
        cin>>n>>m;
        if(n>299000)
        {
            while(1);
        }
        for(int i=0;i<n-1;i++)
        {
            int u,v;
            cin>>u>>v;
            J(u);
            J(v);
            G[u].push_back(v);
            G[v].push_back(u);
        }
        
        for(int i=0;i<20;i++)
            F[1][i]=1;
        
        memset(used, 0, sizeof used);
        dfs(1);
        
        
        for(int i=0;i<m;i++)
        {
            
            int t1,t2;
            cin>>t1>>t2;
            
            int f=lca(t1,t2);
            J(f);
            J(t1);
            J(t2);
            int l=-2*deep[f]+deep[t1]+deep[t2];
            flag[t1].first+=-2;
            flag[t1].second+=2*deep[t1]-l-1+2;
            flag[t2].first+=-2;
            flag[t2].second+=2*deep[t2]-l-1+2;
            
            flag[f].first-=-4;
            flag[f].second-=2*deep[t1]-l-1+2;
            flag[f].second-=2*deep[t2]-l-1+2;
            
            
            ans[1]+=1ll*(deep[t1]-deep[f])*(deep[t2]-deep[f]);
        }
        
        memset(used, 0, sizeof used);
    
    
            dfs2(1);
        memset(used, 0, sizeof used);
        dfs3(1,ans[1]);
        for(int i=1;i<=n;i++){
            cout<<ans[i]<<endl;
        }
        
    }
  • 相关阅读:
    安装和配置nginx
    tomcat 生产发布脚本
    nginx 静态页面访问
    redis 搭建主从
    redis 安装
    perl 操作redis
    mysql 用户除了root一般不建议本地登录
    mysql创建用户
    mysql 查看排序集
    perl 安装Cpan
  • 原文地址:https://www.cnblogs.com/King-of-Dark/p/12236750.html
Copyright © 2020-2023  润新知