10.2晚 模拟继续

100+100+80=280 rank 3
神tm卡常
T1:打表找规律,T2:简单的树规
T3:调了好久,结果蜜汁被卡常,文艺平衡树+乱搞
T1

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
#define mod 1000000007
#define LL long long
LL n,m,ans;
LL qp(LL a,LL b){
    if(a<=0)return 0;
    LL ans=1; a%=mod;
    while(b){
        if(b&1) ans=(ans*a)%mod;
        a=(a*a)%mod;b>>=1;
    }
    return ans;
}
int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        scanf("%lld%lld",&n,&m);
        ans=m%mod;
        if(n==1){printf("%lld\n",ans);continue;}
        ans=(ans*(ans-1))%mod;
        if(n==2){printf("%lld\n",ans);continue;}
        ans=(ans*qp(m-2,n-2))%mod;
        printf("%lld\n",ans);
    }
    return 0;
}

T2

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#define N 1000050
using namespace std;
int e=1,head[N];
struct edge{
    int u,v,next;
}ed[2*N];
void add(int u,int v){
    ed[e].u=u;ed[e].v=v;
    ed[e].next=head[u];
    head[u]=e++;
}
int fa[N],son[N];
double val1[N],w[N],val2[N],ans[N];
void dfs1(int x){
    for(int i=head[x];i;i=ed[i].next){
        int v=ed[i].v;
        if(v==fa[x])continue;
        fa[v]=x;dfs1(v);
        val1[x]+=val1[v]+w[v];
        son[x]++;
    }
    if(son[x])val1[x]/=son[x];
}

void dfs2(int x,double val){
    val2[x]=val;
    for(int i=head[x];i;i=ed[i].next){
        int v=ed[i].v;
        if(v==fa[x])continue;
        if(x!=1)dfs2(v,((val1[x]*son[x]-val1[v]-w[v]+val)/son[x])+w[x]);
        else{
            if(son[x]>1)dfs2(v,((val1[x]*son[x]-val1[v]-w[v]+val)/(son[x]-1))+w[x]);
            else dfs2(v,w[x]);
        }
    }
}
int n;
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%lf",&w[i]);
    for(int i=1,u,v;i<n;i++){
        scanf("%d%d",&u,&v);
        add(u,v);add(v,u);
    }
    dfs1(1);
    dfs2(1,0);
    double MAXN=w[1]+val1[1]; int id=1;
    for(int i=2;i<=n;i++){
        ans[i]=w[i]+(val1[i]*son[i]+val2[i])/(son[i]+1.0);
        if(ans[i]<MAXN){MAXN=ans[i];id=i;}
    }
    printf("%d\n",id);
    return 0;
}

T3

#pragma GCC optimize ("O3")
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#define LL long long
#define N 505000
using namespace std;

int n,m,f[N];
LL k;
char s[N],pp[N];
int num,rk[N];
int a[N],pos;
bool vis[N];

#define tp pair<Treap *,Treap *>
#define size(x) ((x!=NULL)?(x->size):(0))
struct Treap {
    Treap *ch[2];
    int key,val,rev,size;
    Treap (int x){
        key=rand();val=x;size=1;
        rev=0; ch[0]=ch[1]=NULL;
    }
    inline void pushup(){size=size(ch[0])+size(ch[1])+1;}
    inline void rever(){rev^=1;swap(ch[0],ch[1]);}
    inline void pushdown(){
        if(!rev)return;
        if(ch[0])ch[0]->rever();
        if(ch[1])ch[1]->rever();
        rev=0;
    }
}*root;

inline Treap * merge(Treap* a,Treap* b){
    if(!a)return b;
    if(!b)return a;
    if(a->key<=b->key){
        a->pushdown();
        a->ch[1]=merge(a->ch[1],b);
        a->pushup();return a;
    }
    else{
        b->pushdown();
        b->ch[0]=merge(a,b->ch[0]);
        b->pushup();return b;
    }
}
inline tp split(Treap *a,int k){
    if(!a)return tp(NULL,NULL);
    tp x;
    a->pushdown();
    if(size(a->ch[0])>=k){
        x=split(a->ch[0],k);
        a->ch[0]=x.second;
        a->pushup();x.second=a;
    }
    else{
        x=split(a->ch[1],k-size(a->ch[0])-1);
        a->ch[1]=x.first;
        a->pushup(); x.first=a;
    }
    return x;
}
inline void work(int l,int r){
    tp x=split(root,l-1);
    tp y=split(x.second,r-l+1);
    Treap *z=y.first;
    z->rever();
    root=merge(x.first,merge(z,y.second));
}
Treap *st[N];
Treap *build(int tot){
    Treap *now,*last;
    int top=0;
    for(int i=1;i<=tot;i++){
        now=new Treap (i);
        last=NULL;
        while(top&&st[top]->key>now->key){
            st[top]->pushup();
            last=st[top--];
        }
        now->ch[0]=last;
        now->pushup();
        if(top){st[top]->ch[1]=now;st[top]->pushup();}
        st[++top]=now;
    }
    while(top) st[top--]->pushup();
    return st[1];
}
int now =0;
inline void dfs(Treap * a){
    if(!a)return ;
    a->pushdown();
    dfs(a->ch[0]);
    f[++now]=a->val;
    dfs(a->ch[1]);
    //printf("%d  %d\n",x,y.first->val);
}

inline void get_26(LL x){
    while(x){
        a[++pos]=x%26;
        x/=26;
    }
}
inline int read(){
    int a=0; char ch=getchar();
    while(ch<'0'||ch>'9')ch=getchar();
    while(ch>='0'&&ch<='9'){a=a*10+(ch^48);ch=getchar();}
    return a;
}
int main(){
    n=read(); m=read();
    scanf("%lld",&k);
    scanf("%s",s+1);
    root=build(n);
    for(int i=1,l,r;i<=m;++i){
        l=read(); r=read();
        if(l>r)swap(l,r);
        work(l,r);
    }
    dfs(root);
    for(int i=1;i<=n;++i){
        if(s[i]=='?'&&!vis[i]){
            int now=i,final;
            while(s[f[now]]=='?'&&!vis[f[now]]){
                vis[now]=1;
                now=f[now];
            }
            vis[now]=1;
            final=f[now];
            if(s[final]!='?'){
                for(now=i;now!=final;now=f[now])
                    s[now]=s[final];
            }
            else{
                rk[i]=++num;
                for(now=f[i];now!=final;now=f[now]){
                    rk[now]=num;
                }
            }
        }
    }
    get_26(--k);
    for(int i=1;i<=n;++i){
        if(s[i]=='?')s[i]='a'+a[num-rk[i]+1];
        printf("%c",s[i]);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值