zoukankan      html  css  js  c++  java
  • contest 1.20

    B.矩阵快速幂

    等比数列二分求和

    #include <iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
     
    int n,k,mod;
    const int MAXN=35;
    struct Mat{
        int n,m;
        int mat[MAXN][MAXN];
        Mat(){
            memset(mat,0,sizeof(mat));
            n=MAXN,m=MAXN;
        }
        Mat(int x,int y){
            memset(mat,0,sizeof(mat));
            n=x,m=y;
        };
        Mat operator*(Mat b){
            Mat c(n,b.m);
            for(int i=0;i<n;i++)
                for(int j=0;j<b.m;j++){
                    for(int k=0;k<m;k++){
                        c.mat[i][j]+=(mat[i][k]*b.mat[k][j])%mod;
                        c.mat[i][j]%=mod;
                    }
                }
            return c;
        }
        Mat operator+(Mat b){
            Mat c(n,m);
            for(int i=0;i<n;i++)
                for(int j=0;j<m;j++)
                    c.mat[i][j]=(mat[i][j]+b.mat[i][j])%mod;
            return c;
        }
        void in(){
            for(int i=0;i<n;i++)
                for(int j=0;j<m;j++)
                    scanf("%d",&mat[i][j]);
        }
        void out(){
            for(int i=0;i<n;i++){
                for(int j=0;j<m;j++)
                    printf("%d%c",mat[i][j],j==m-1?'
    ':' ');
            }
        }
    }E;
     
    Mat qpow(Mat a,int b){Mat ret=E; while(b){ if(b&1) ret=ret*a; a=a*a; b>>=1;} return ret;}
     
    Mat cal(Mat a,int k){//二分求等比数列和--a+a^2+a^3+...+a^k
      if(k==1) return a;
      else if(k&1){
        Mat cur=qpow(a,k/2+1);
        return cal(a,k/2)*(E+cur)+cur;
      }
      else return cal(a,k/2)*(E+qpow(a,k/2));
    }
     
    int main()
    {
        scanf("%d%d%d",&n,&k,&mod);
        E.n=n,E.m=n;
        for(int i=0;i<n;i++)
          for(int j=0;j<n;j++)
            E.mat[i][j]=(i==j?1:0);
        Mat now(n,n);
        now.in();
        now=cal(now,k);
        now.out();
        return 0;
    }
    View Code

    C.发财兔序列

    莫队+离散化+set

    #include <iostream>
    #include<cstdio>
    #include<cmath>
    #include<set>
    #include<algorithm>
    using namespace std;
    
    set<int> s;set<int>::iterator it;
    int n,m;
    int a[100005],b[100005],z;
    struct Query{int l,r,id;}q[100005];
    int cnt[100005],tot[100005];
    int ans[100005];
    int maxn=1;
    
    int getid(int x){return lower_bound(b+1,b+1+z,x)-b;}
    
    bool cmp(Query a,Query b){
      int block=sqrt(n);
      if(a.l/block!=b.l/block) return a.l/block<b.l/block;
      else return a.r<b.r;
    }
    
    inline void add(int pos){
      int id=getid(a[pos]);
      tot[cnt[id]]--;
      if(tot[cnt[id]]==0) s.erase(cnt[id]);
      cnt[id]++;
      tot[cnt[id]]++;
      if(tot[cnt[id]]==1) s.insert(cnt[id]);
      it=s.end(); it--;
      maxn=*it;
    }
    
    inline void sub(int pos){
      int id=getid(a[pos]);
      tot[cnt[id]]--;
      if(tot[cnt[id]]==0) s.erase(cnt[id]);
      cnt[id]--;
      tot[cnt[id]]++;
      if(tot[cnt[id]]==1) s.insert(cnt[id]);
      it=s.end(); it--;
      maxn=*it;
    }
    
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++) scanf("%d",&a[i]),b[i]=a[i];
        sort(b+1,b+1+n);z=unique(b+1,b+1+n)-(b+1);
        for(int i=1;i<=m;i++){
            scanf("%d%d",&q[i].l,&q[i].r);
            q[i].id=i;
        }
        sort(q+1,q+1+m,cmp);
        int L=1,R=0;
        for(int i=1;i<=m;i++){
            while(q[i].r>R) R++,add(R);
            while(q[i].r<R) sub(R),R--;
            while(q[i].l>L) sub(L),L++;
            while(q[i].l<L) L--,add(L);
            ans[q[i].id]=maxn;
        }
        for(int i=1;i<=m;i++) printf("%d
    ",ans[i]);
        return 0;
    }
    View Code

    E.发财兔求和

    先把各个颜色分离,再把同种颜色中的奇编号和偶编号分离

    推公式

    #include <iostream>
    #include<cstdio>
    #include<cstring>
    #include<vector>
    #include<algorithm>
    #define mod 10007
    typedef long long ll;
    using namespace std;
    
    ll n,m;
    struct Node{ll id,num;};
    ll color[100005],num[100005];
    vector<Node> v1[100005];
    vector<Node> v2[100005];
    
    int main()
    {
        scanf("%lld%lld",&n,&m);
        for(ll i=1;i<=n;i++) scanf("%lld",&num[i]);
        for(ll i=1;i<=n;i++) scanf("%lld",&color[i]);
        for(ll i=1;i<=n;i++){
            if(i%2==1) v1[color[i]].push_back(Node{i,num[i]});
            else v2[color[i]].push_back(Node{i,num[i]});
        }
        ll ans=0;
        for(ll i=1;i<=m;i++){
            if(v1[i].size()!=0){
              ll siz=v1[i].size();
              ll sum_num=0,sum_id=0,sum_product=0;
              for(ll j=0;j<siz;j++){
                sum_id=(sum_id+v1[i][j].id)%mod;
                sum_num=(sum_num+v1[i][j].num)%mod;
                sum_product=(sum_product+v1[i][j].id*v1[i][j].num%mod)%mod;
              }
              for(ll j=0;j<siz;j++){
                ans=(ans+(siz-1)*v1[i][j].id%mod*v1[i][j].num%mod+v1[i][j].id*(sum_num-v1[i][j].num)%mod+v1[i][j].num*(sum_id-v1[i][j].id)%mod+(sum_product-v1[i][j].id*v1[i][j].num%mod))%mod;
              }
            }
            if(v2[i].size()!=0){
              ll siz=v2[i].size();
              ll sum_num=0,sum_id=0,sum_product=0;
              for(ll j=0;j<siz;j++){
                sum_id=(sum_id+v2[i][j].id)%mod;
                sum_num=(sum_num+v2[i][j].num)%mod;
                sum_product=(sum_product+v2[i][j].id*v2[i][j].num%mod)%mod;
              }
              for(ll j=0;j<siz;j++){
                ans=(ans+(siz-1)*v2[i][j].id%mod*v2[i][j].num%mod+v2[i][j].id*(sum_num-v2[i][j].num)%mod+v2[i][j].num*(sum_id-v2[i][j].id)%mod+(sum_product-v2[i][j].id*v2[i][j].num%mod))%mod;
              }
            }
        }
        ans=(ans+mod)%mod;
        ans=ans*5004%mod;
        printf("%lld
    ",ans);
        return 0;
    }
    View Code

    D.有趣的数

     构造

    #include <iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    typedef long long ll;
    using namespace std;
    
    ll p[20];
    ll k,m,len;
    char s[20];
    
    ll cal(ll x){
      sprintf(s,"%lld",x);
      len=strlen(s);
      ll now=1,t=0,ret=0;
      for(ll i=0;i<len;i++){
        t=t*10+s[i]-'0';
        ret+=(t-now+1);
        now*=10;
      }
      return ret;
    }
    
    int main()
    {
        p[0]=1;
        for(ll i=1;i<=18;i++) p[i]=p[i-1]*10;
        scanf("%lld%lld",&k,&m);
        ll flag=-1;
        for(ll i=0;i<=18;i++){
            if(p[i]==k) {flag=i;break;}
        }
        if(flag!=-1){
            if(flag+1==m) printf("%lld
    ",k);
            else puts("0");
            return 0;
        }
        ll min_m=cal(k);
        if(m==min_m) printf("%lld
    ",k);
        else if(m<min_m) puts("0");
        else{
            m-=min_m;
            ll ans=p[len],now=1;
            while(1){
                ll tmp=k*p[now]-ans;
                if(tmp>=m) break;
                else{
                    m-=tmp;
                    now++,ans*=10;
                }
            }
            ans+=m-1;
            printf("%lld
    ",ans);
        }
        return 0;
    }
    View Code
    转载请注明出处:https://www.cnblogs.com/lllxq/
  • 相关阅读:
    下载文件c#
    系统蓝屏重起:如何修改设置,记录系统蓝屏重起的错误
    Repeater中的行数
    2010617 重装系统遇到的问题
    ajax 修改select的值 返回的值中有逗号
    GPS数据接收 串口调试感受
    Nios II实用之音频控制
    【笔记】VB控件MSComm功能介绍
    【摘】程序员版同桌的你
    AJAX Control Toolkit ——DragPanelExtender(拖拽面板)
  • 原文地址:https://www.cnblogs.com/lllxq/p/10294840.html
Copyright © 2011-2022 走看看