2020牛客多校第7场赛后感

本博客主要目的为个人使用,也欢迎读者讨论。

 

1.题难懂

2.自己傻

3.知识少

 

A. Social Distancing 

题意:在坐标系中原点为圆心,r为半径的圆内放n个点,求$\sum_{i=1}^{n-1} \sum_{j=i+1}^n d(i,j)^2$最大值。选择的坐标是整数坐标。$1 \le n \le 8, 1\le r \le 30$

 

可以用dp。(这个真没想到,我还以为是贪心)

f[i,x,y]表示用了i个人,x表示横坐标之和,y表示纵坐标之和。

那么$f[i,x,y]=\sum_{i=1}^{n-1} \sum_{j=i+1}^n ((x_i-x_j)^2+(y_i-y_j)^2)=\sum_{i=1}^{n-1} \sum_{j=i+1}^n (x_i^2+x_j^2-2x_ix_j+y_i^2+y_j^2-2y_iy_j)$

可以推出$f[i,x+j,y+k]=max\{f[i-1,x,y]+(i-1)(j^2+k^2)+\frac{f[i-1,x,y]+x^2+y^2}{n-1}-2xj-2yk\}$

如果怕超时的话,可以预处理。

 

下面是dp的代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#include<cmath>
#include<queue>
using namespace std;

typedef pair<int,int> PII;

struct Trip{
    int x, y, d;
    Trip(int x=0, int y=0, int d=0):x(x),y(y),d(d){}
};

int n, r;
//vector<Trip> f[10]; 
//vector<int> Pos;
int f[10][600][600], base=300;

int cal(int x, int r){
    if(x<0) x=-x;
    return sqrt(r*r-x*x);
}

int main(){
    //freopen("A.txt","w",stdout);
    for(int i=1; i<=30; ++i){
        memset(f,0,sizeof(f));
        r=i;
        for(int n=2; n<=8; ++n){
            for(int xi=-300; xi<=300; ++xi){
                for(int yi=-300; yi<=300; ++yi){
                    if(n>2 && f[n-1][xi+base][yi+base]==0) continue;
                    if(n==2 && xi*xi+yi*yi>r*r) continue;
                    for(int xii=-r; xii<=r; ++xii){
                        int yii_max=sqrt(r*r-xii*xii);
                        for(int yii=-yii_max; yii<=yii_max; ++yii){
                            f[n][xi+xii+base][yi+yii+base]=max(f[n][xi+xii+base][yi+yii+base],\
                                f[n-1][xi+base][yi+base]+(n-1)*(xii*xii+yii*yii)+(f[n-1][xi+base][yi+base]+xi*xi+yi*yi)/(n-1)-2*xii*xi-2*yii*yi);
                        }
                    }
                }
            }
            int ans=0;
            for(int i=-300; i<=300; ++i){
                for(int j=-300; j<=300; ++j){
                    ans=max(ans,f[n][i+base][j+base]);
                }
            }
            printf("\t%d", ans);
            if(n==8) puts("");
        }
        
    }
    getchar();
    return 0;
}
A dp

下面是打表的代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

int a[10][40];

int main(){
a[1][1]=0; a[2][1]=4; a[3][1]=8; a[4][1]=16; a[5][1]=24; a[6][1]=36; a[7][1]=48; a[8][1]=64; 
a[1][2]=0; a[2][2]=16; a[3][2]=32; a[4][2]=64; a[5][2]=96; a[6][2]=144; a[7][2]=192; a[8][2]=256; 
a[1][3]=0; a[2][3]=36; a[3][3]=76; a[4][3]=144; a[5][3]=218; a[6][3]=324; a[7][3]=432; a[8][3]=576; 
a[1][4]=0; a[2][4]=64; a[3][4]=130; a[4][4]=256; a[5][4]=384; a[6][4]=576; a[7][4]=768; a[8][4]=1024; 
a[1][5]=0; a[2][5]=100; a[3][5]=224; a[4][5]=400; a[5][5]=624; a[6][5]=900; a[7][5]=1224; a[8][5]=1600; 
a[1][6]=0; a[2][6]=144; a[3][6]=312; a[4][6]=576; a[5][6]=880; a[6][6]=1296; a[7][6]=1740; a[8][6]=2304; 
a[1][7]=0; a[2][7]=196; a[3][7]=416; a[4][7]=784; a[5][7]=1188; a[6][7]=1764; a[7][7]=2356; a[8][7]=3136; 
a[1][8]=0; a[2][8]=256; a[3][8]=554; a[4][8]=1024; a[5][8]=1572; a[6][8]=2304; a[7][8]=3102; a[8][8]=4096; 
a[1][9]=0; a[2][9]=324; a[3][9]=722; a[4][9]=1296; a[5][9]=2014; a[6][9]=2916; a[7][9]=3954; a[8][9]=5184; 
a[1][10]=0; a[2][10]=400; a[3][10]=896; a[4][10]=1600; a[5][10]=2496; a[6][10]=3600; a[7][10]=4896; a[8][10]=6400; 
a[1][11]=0; a[2][11]=484; a[3][11]=1064; a[4][11]=1936; a[5][11]=2984; a[6][11]=4356; a[7][11]=5872; a[8][11]=7744; 
a[1][12]=0; a[2][12]=576; a[3][12]=1248; a[4][12]=2304; a[5][12]=3520; a[6][12]=5184; a[7][12]=6960; a[8][12]=9216; 
a[1][13]=0; a[2][13]=676; a[3][13]=1512; a[4][13]=2704; a[5][13]=4224; a[6][13]=6084; a[7][13]=8280; a[8][13]=10816; 
a[1][14]=0; a[2][14]=784; a[3][14]=1746; a[4][14]=3136; a[5][14]=4870; a[6][14]=7056; a[7][14]=9564; a[8][14]=12544; 
a[1][15]=0; a[2][15]=900; a[3][15]=2016; a[4][15]=3600; a[5][15]=5616; a[6][15]=8100; a[7][15]=11016; a[8][15]=14400; 
a[1][16]=0; a[2][16]=1024; a[3][16]=2264; a[4][16]=4096; a[5][16]=6336; a[6][16]=9216; a[7][16]=12456; a[8][16]=16384; 
a[1][17]=0; a[2][17]=1156; a[3][17]=2600; a[4][17]=4624; a[5][17]=7224; a[6][17]=10404; a[7][17]=14160; a[8][17]=18496; 
a[1][18]=0; a[2][18]=1296; a[3][18]=2888; a[4][18]=5184; a[5][18]=8056; a[6][18]=11664; a[7][18]=15816; a[8][18]=20736; 
a[1][19]=0; a[2][19]=1444; a[3][19]=3218; a[4][19]=5776; a[5][19]=9008; a[6][19]=12996; a[7][19]=17666; a[8][19]=23104; 
a[1][20]=0; a[2][20]=1600; a[3][20]=3584; a[4][20]=6400; a[5][20]=9984; a[6][20]=14400; a[7][20]=19584; a[8][20]=25600; 
a[1][21]=0; a[2][21]=1764; a[3][21]=3912; a[4][21]=7056; a[5][21]=10942; a[6][21]=15876; a[7][21]=21500; a[8][21]=28224; 
a[1][22]=0; a[2][22]=1936; a[3][22]=4344; a[4][22]=7744; a[5][22]=12080; a[6][22]=17424; a[7][22]=23688; a[8][22]=30976; 
a[1][23]=0; a[2][23]=2116; a[3][23]=4712; a[4][23]=8464; a[5][23]=13144; a[6][23]=19044; a[7][23]=25808; a[8][23]=33856; 
a[1][24]=0; a[2][24]=2304; a[3][24]=5138; a[4][24]=9216; a[5][24]=14326; a[6][24]=20736; a[7][24]=28122; a[8][24]=36864; 
a[1][25]=0; a[2][25]=2500; a[3][25]=5612; a[4][25]=10000; a[5][25]=15624; a[6][25]=22500; a[7][25]=30624; a[8][25]=40000; 
a[1][26]=0; a[2][26]=2704; a[3][26]=6062; a[4][26]=10816; a[5][26]=16896; a[6][26]=24336; a[7][26]=33120; a[8][26]=43264; 
a[1][27]=0; a[2][27]=2916; a[3][27]=6536; a[4][27]=11664; a[5][27]=18184; a[6][27]=26244; a[7][27]=35664; a[8][27]=46656; 
a[1][28]=0; a[2][28]=3136; a[3][28]=6984; a[4][28]=12544; a[5][28]=19488; a[6][28]=28224; a[7][28]=38266; a[8][28]=50176; 
a[1][29]=0; a[2][29]=3364; a[3][29]=7520; a[4][29]=13456; a[5][29]=20968; a[6][29]=30276; a[7][29]=41200; a[8][29]=53824; 
a[1][30]=0; a[2][30]=3600; a[3][30]=8084; a[4][30]=14400; a[5][30]=22480; a[6][30]=32400; a[7][30]=44076; a[8][30]=57600; 

    int T; scanf("%d", &T);
    for(int i=1; i<=T; ++i){
        int n, r;
        scanf("%d%d", &n, &r);
        printf("%d\n", a[n][r]);
    }
    return 0;
}
A 打表

 

我还学了学模拟退火,但错误率很高,正确率大约1/3,只可作为参考。可能是我还不会模拟退火。

下面是我模拟退火的代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<ctime>
#include<vector>
#include<map>
using namespace std;

typedef pair<int,int> PII;

int n, r;
int ans[8];
vector<PII> V, V2;
map<int,int> M;

double calw(int a[]){
    double res=0;
    for(int i=0; i<n-1; ++i){
        for(int j=i+1; j<n; ++j){
            int tx=V[a[i]].first-V[a[j]].first, ty=V[a[i]].second-V[a[j]].second;
            res+=tx*tx+ty*ty;
        }
    }
    return res;
}

void gettmp(int a[], int b[], double T, int sz){
    int cnt=0;
    for(int i=0; i<n; ++i){
        do{
            a[i]=b[i]+(rand()*2-RAND_MAX)*T; while(a[i]<0) a[i]+=sz; a[i]%=sz;
        }while(0);
        M[a[i]]=1;
    }
}

void sa(double T, double down, double &answ, int sz){
    int cnt=0; double resw=answ;
    int res[8];
    for(int i=0; i<n; ++i) res[i]=ans[i];
    while(T>1e-5){
        int tmp[8]; M.clear();
        gettmp(tmp,res,T,sz);
        double tw=calw(tmp);
        if(tw>answ){
            for(int i=0; i<n; ++i) ans[i]=res[i]=tmp[i];
            answ=resw=tw;
        }else if(tw>resw || exp(tw-resw/T)*RAND_MAX>rand()){
            for(int i=0; i<n; ++i) res[i]=tmp[i];
            resw=tw;
        }
        T*=down;
    }
}

double SA(){
    V2.clear(); V.clear();
    for(int i=r-1, j=0; i>0; --i){
        while(i*i+(j+1)*(j+1)<=r*r) j++;
        V2.push_back(PII(j,i));
    }
    int sz=V2.size();
    V.push_back(PII(0,r));
    for(int i=0; i<sz; ++i) V.push_back(V2[i]);
    V.push_back(PII(r,0));
    for(int i=0; i<sz; ++i) V.push_back(PII(V2[i].first,-V2[i].second));
    V.push_back(PII(0,-r));
    for(int i=0; i<sz; ++i) V.push_back(PII(-V2[i].first,-V2[i].second));
    V.push_back(PII(-r,0));
    for(int i=0; i<sz; ++i) V.push_back(PII(-V2[i].first,V2[i].second));
    sz=V.size();
    double T=0.1, down=0.995, answ=calw(ans);
    for(int i=1; i<=10; ++i){
        sa(T,down,answ,sz);
    }
    return answ;
}

int main(){
    srand((unsigned)time(NULL));
//    freopen("A.txt","w",stdout);
    for(int i=1; i<=30; ++i){
        for(int j=1; j<=8; ++j){
            n=j; r=i;
            for(int i=0; i<n; ++i) ans[i]=0;
            double answ=SA();
            printf("\t%5.0lf", answ);
        }
        puts("");
    }
}
A 模拟退火

 

B. Mask Allocation 

此题最大困难在于读懂题意。

题意:给两个数a,b,求一个数列,使得数列数之和等于a*b,可拼成a个b或b个a,且字典序最大。$n,m \le 10^4$

 

假设a<b,那么数列中不能有题超过a的数字。a个a加上a*(b-a)个1一定是可行的。现在保住前面a个a,让后面最大。将b-a看作t,那么现在要求a*t的数列最大,这又回到了原题目,因此可以用循环的形式解决问题。

 

代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
 
int n, m;
vector<int> ans;
 
int main(){
    ios::sync_with_stdio(false);
    int T; cin>>T;
    while(T--){
        ans.clear();
        cin>>n>>m;
        while(n&&m){
            if(n>m) swap(n,m);
            for(int i=1; i<=n; ++i){
                ans.push_back(n);
            }
            m-=n;
        }
        int sz=ans.size();
        cout<<sz<<endl;
        for(int i=0; i<sz; ++i) cout<<ans[i]<<(i==sz-1?'\n':' ');
    }
}
B

 

C. A National Pandemic 

题意:给一棵n个点的树,初始点权都为0,后有m个操作,含3种类型:"1 x y"表示每个点u点权加上y-dis(x,u),其中dis(x,u)为x到u的距离;"2 x"表示将x点点权变为min(x点权,0);"3 x"表示询问x点权。$1 \le n, m \le 5*10^4, y \le 10^4$

 

应该算是一道典型的树上的题吧。对于1操作,y-dis(x,u)=y-dep(x)-dep(u)+2*dep(lca);这里只有dep(lca)是x,u共同决定的,做法是将x到根的路径上的所有点权加2,询问时求点到根的点权和即可。对于2,另外设一个数组记录即可。

 

代码如下:(其中大部分用的是树链剖分模板,只看struct TtoC以外的部分即可)

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;

typedef long long LL;
const int N=50000+10;

int n, m;
LL val[N], a[N];
LL sumw, sumdep, cnt;

struct Graph{
    vector<int> G[N];
    
    void init(){
        for(int i=0; i<N; ++i){
            G[i].clear();
        }
    }
    
    void add(int u, int v){
        G[u].push_back(v);
        G[v].push_back(u);
    }
    
};

struct TtoC{//树链剖分 TreeToChain
    Graph g;    //
    int r;        //根结点 
    int dfntot;
    int dfn[N], size[N], son[N], top[N], fa[N], dep[N], nfd[N];
    
    LL sum[N<<2], lazy[N<<2];
    
    void init(int r, Graph &g){
        //for(int i=0; i<N; ++i) this->g.G[i].clear();
        this->r=r;
        this->g=g;
        dfntot=0;
        memset(dep,0,sizeof(dep)); dep[r]=1;
        memset(son,0,sizeof(son));
        fa[r]=0;
        memset(lazy,0,sizeof(lazy));
    }
    
    void start(int r, Graph& g){
        init(r,g);
        dfs1(r);    //得到size, fa, dep, son 
        dfs2(r,r);    //得到dfn, top 
        build(1,1,n);    //线段树的建立
    }
    
    void dfs1(int u){
        size[u]=1;
        int sz=g.G[u].size();
        for(int i=0; i<sz; ++i){
            int v=g.G[u][i];
            if(dep[v]) continue;
            dep[v]=dep[u]+1; fa[v]=u;
            dfs1(v);
            size[u]+=size[v];
            if(son[u]==0 || size[v]>size[son[u]]) son[u]=v;
        }
    }
    
    void dfs2(int u, int ffa){
        dfn[u]=++dfntot;
        nfd[dfntot]=u;
        top[u]=ffa;
        if(son[u]){
            dfs2(son[u],ffa);
        }
        int sz=g.G[u].size();
        for(int i=0; i<sz; ++i){
            int v=g.G[u][i];
            if(v==fa[u] || v==son[u]) continue;
            dfs2(v,v);
        }
    }
    
    void changeuv(int u, int v, int w){
        int tu=top[u], tv=top[v];
        while(tu!=tv){
            if(dep[tu]<dep[tv]){
                swap(u,v);
                swap(tu,tv);
            }
            change(1,1,n,dfn[tu],dfn[u],w);
            u=fa[tu];
            tu=top[u];
        }
        if(dep[u]<dep[v]) swap(u,v);
        change(1,1,n,dfn[v],dfn[u],w);
    }
    
    LL queryuv(int u, int v){
        LL res=0;
        int tu=top[u], tv=top[v];
        while(tu!=tv){
            if(dep[tu]<dep[tv]){
                swap(u,v);
                swap(tu,tv);
            }
            res+=query(1,1,n,dfn[tu],dfn[u]);
            u=fa[tu];
            tu=top[u];
        }
        if(dep[u]<dep[v]) swap(u,v);
        res+=query(1,1,n,dfn[v],dfn[u]);
        return res;
    }
    
    //以下为线段树
    void build(int rt, int l, int r){
        if(l==r){
            sum[rt]=val[nfd[l]];
        }else{
            int mid=l+r>>1;
            build(rt<<1,l,mid);
            build(rt<<1|1,mid+1,r);
            sum[rt]=sum[rt<<1]+sum[rt<<1|1];
        }
    }
    
    void change(int rt, int l, int r, int L, int R, int w){
        if(R<l || r<L) return;
        if(L<=l && r<=R){
            lazy[rt]+=w;
            return;
        }
        sum[rt]+=w*1ll*(R-L+1);
        int mid=l+r>>1;
        if(R<=mid) change(rt<<1,l,mid,L,R,w);
        else if(L>mid) change(rt<<1|1,mid+1,r,L,R,w);
        else { change(rt<<1,l,mid,L,mid,w); change(rt<<1|1,mid+1,r,mid+1,R,w); }
    }
    
    LL query(int rt, int l, int r, int L, int R){
        if(R<l || r<L) return 0;
        if(L<=l && r<=R) return sum[rt]+lazy[rt]*(r-l+1);
        int mid=l+r>>1;
        LL res=0;
        if(R<=mid) res=query(rt<<1,l,mid,L,R);
        else if(L>mid) res=query(rt<<1|1,mid+1,r,L,R);
        else res=query(rt<<1,l,mid,L,mid)+query(rt<<1|1,mid+1,r,mid+1,R);
        return res+lazy[rt]*(R-L+1);
    }
};

Graph g;
TtoC ttc;

LL query(int u){
    return sumw-sumdep-cnt*ttc.dep[u]+ttc.queryuv(1,u)+a[u];
}

int main(){
    int T; scanf("%d", &T);
    while(T--){
        g.init();
        memset(val,0,sizeof(val));
        memset(a,0,sizeof(a));
        sumw=sumdep=cnt=0;
        
        scanf("%d%d", &n, &m);
        for(int i=1, u, v; i<n; ++i){
            scanf("%d%d", &u, &v);
            g.add(u,v);
        }
        
        ttc.start(1,g);
        for(int i=1; i<=m; ++i){
            int opt, x; LL y;
            scanf("%d", &opt);
            switch(opt){
                case 1:
                    scanf("%d%lld", &x, &y);
                    ttc.changeuv(1,x,2);
                    sumw+=y;
                    sumdep+=ttc.dep[x];
                    cnt++;
                    break;
                case 2:
                    scanf("%d", &x);
                    y=query(x);
                    if(y>0) a[x]-=y;
                    break;
                case 3:
                    scanf("%d", &x);
                    printf("%lld\n", query(x));
                    break;
            }
        }
    }
    return 0;
}
C

 

树上的有关知识该复习了,可以看看 qtree

 

D. ac 

没看,应该是水题

 

H. Dividing 

题意:定义满足以下条件为the Legend Tuple:1.(1,k)是;2.如果(a,b)是,则(a+b,b)也是;3.若(a,b)是,则(a*b,b)也是。现求所有满足$1 \le n \le N, 1\le k \le K$的(n,k)个数。$1 \le N, K \le 10^{12}$

 

对于固定的k,(n,k)是the legend tuple的充要条件是n%k=1或n%k=0。因此当k=1或2时,所有n都满足;当k>2时,n个数是n/k+(n-1)/k+1。

对于$\sum_{i=1}^k \frac{n}{i} $每项下取整是有方法的,时间复杂度O(logn)。

 

代码见下:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

typedef long long LL;
const LL P=1e9+7;
LL n, k;

// n/1 + n/2 + ... + n/k向下取整 
LL cal(LL n, LL k){
    if(!n||!k) return 0;
    LL res=0, i, j;
    for(i=1; i<=k; i=j+1){
        j=n/(n/i);
        res=(res+(n/i)%P*(j-i+1)%P)%P;
    }
    return (res-n/(i-1)%P*(i-k-1)%P+P)%P;
}

//向上取整 
LL cal22(LL n, LL k){
    if(n==k) return (cal(n-1,k-1)+k)%P;
    return (cal(n-1,k)+k)%P;
}

LL shang(LL a, LL b){
    return (a+b-1)/b;
}
int main(){
//    freopen("data.txt","r",stdin);
//    freopen("my.txt","w",stdout);
    ios::sync_with_stdio(false);
    cin>>n>>k;
    if(k<3){
        cout<<n*k%P<<endl;
        return 0;
    }
    LL ans;
    if(n>=k) ans=cal(n,k)+cal22(n,k)-n/2%P-shang(n,2)%P+P+P, ans%=P;
    else ans=cal(n,n)+cal22(n,n)-n/2%P-shang(n,2)%P+k-n+P+P, ans%=P;
    cout<<ans<<endl;
}
H

题解用了另一种方法,我没看懂,就不写在这里了。

 

I. Valuable Forests 

题意:定义一个森林的值为森林中所有点的度数的平方和。T次询问,每次求所有含n个带标号的点的森林的值之和,结果对P取模。$1 \le T \le 5000, 1 \le n \le 5000, 1 \le P \le 2^{30} 且为质数$

 

这题的主要攻克点:

1. Cayley n顶点树数定理:

n个点的带标号树个数为$n^{n-2}$。

证明方法:将一棵树和一个数列$\{a_i,a_2,...a_{n-2}\}$对应起来,其中$1 \le a_i \le n$,因此共$n^{n-2}$个。同时,每个数$i$出现$d_i-1$次,$d_i$是度数。

2. 递推的方式。

具体实现方式一篇题解写的很好,我再写也不过是复述而已:https://blog.nowcoder.net/n/026e1c74bc9949e2b57584ac83074404

 

下面是我的代码:

//code by cyh
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;

typedef long long LL;
const int N=5000+10;

LL p;
LL fn[N], fv[N], tn[N], tv[N], tmp[N];
LL fa[N], fb[N], CC[N][N];

LL Pow(LL x, LL n, LL P){
    if(n==0) return 1;
    LL tmp=Pow(x,n/2,P);
    if(n&1) return tmp*tmp%P*x%P;
    return tmp*tmp%P;
}

void init(int P){
    LL x, y;
    fa[0]=1; fn[0]=1; tv[1]=0; tn[0]=tn[1]=1;
    CC[0][0]=1;
    for(int i=1; i<N; ++i){
        CC[i][0]=1;
        for(int j=1; j<=i; ++j){
            CC[i][j]=(CC[i-1][j]+CC[i-1][j-1])%P;
        }
    }
    for(int i=2; i<N; ++i) tn[i]=Pow(i,i-2,P);
    for(int n=1; n<N; ++n){
        for(int i=0; i<n; ++i) fn[n]=(fn[n]+CC[n-1][i]*fn[n-1-i]%P*tn[i+1]%P)%P;
    }
    for(int n=2; n<N; ++n){
        tmp[0]=1;
        for(int i=1; i<=n; ++i) tmp[i]=tmp[i-1]*(n-1)%P;
        for(int i=0; i<n; ++i) tv[n]=(tv[n]+CC[n-2][i]*(i+1)%P*(i+1)%P*tmp[n-2-i]%P)%P;
        tv[n]=tv[n]*n%P;
    }
    for(int n=1; n<N; ++n){
        for(int i=0; i<n; ++i) fv[n]=(fv[n]+CC[n-1][i]*(fv[n-i-1]*tn[i+1]%P+fn[n-i-1]*tv[i+1]%P)%P)%P;
    }

}

int main(){
//    freopen("data.txt","r",stdin);
//    freopen("my.txt","w",stdout);
    int T; scanf("%d%lld", &T, &p);
    init(p);
    for(int i=1, x; i<=T; ++i){
        scanf("%d", &x);
        printf("%lld\n", fv[x]);
    }
    return 0;
}

I
I

 

posted @ 2020-08-07 22:38  white514  阅读(107)  评论(0编辑  收藏  举报