T1
就是个签到题
第一个可以选m
第二个选m-1
第三个 m-2
之后都是m-2
特判n=1/2,m一开始就要mod,不然炸long long
(就这么道不是题的题,我特么考试的时候竟然觉得他是 矩阵乘优化dp....,100分啊啊啊啊啊啊啊啊啊)
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cstdlib>
#define ll long long
using namespace std;
const int mod=1000000007;
ll n,m;
ll ans;
int T;
ll mi(ll a,ll ci,int mod)
{
ll ans=1;
a%=mod;
while(ci)
{
if(ci&1)
ans=ans*a%mod;
a=a*a%mod;
ci>>=1;
}
return ans;
}
int main(){
scanf("%d",&T);
while(T--)
{
scanf("%lld%lld",&n,&m);
m%=mod;
ans=m%mod;
if(n>1)
ans=ans*(m-1)%mod;
if(n>2)
ans=ans*mi(m-2,n-2,mod)%mod;
printf("%lld
",ans);
}
}
T2
两遍dfs
分每个点做root和不做root 两种情况
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define mem(a,b) memset(a,b,sizeof(a))
#define ll long long
#define dd double
using namespace std;
const dd esp=0.000000001;
inline dd abss(dd x){return x<0?-x:x;}
inline int read()
{
char q=getchar();int ans=0;
while(q<'0'||q>'9')q=getchar();
while(q>='0'&&q<='9'){ans=ans*10+q-'0';q=getchar();}
return ans;
}
const int N=1000006;
struct son
{
int v,next;
}a1[N*3];
int first[N*3],e;
void addbian(int u,int v)
{
a1[e].v=v;
a1[e].next=first[u];
first[u]=e++;
}
int n;
int A[N];
dd deg[N];
dd sh[N],xi[N],shr[N],xir[N];
int fa[N];
void dfs1(int x)
{
xi[x]=(dd)A[x];
xir[x]=(dd)A[x];
int temp;
for(int i=first[x];i!=-1;i=a1[i].next)
{
temp=a1[i].v;
if(temp==fa[x])
continue;
fa[temp]=x;
dfs1(temp);
xir[x]+=(xi[temp]*(1.0/deg[x]));
if(deg[x]>1)
xi[x]+=(xi[temp]*(1.0/(deg[x]-1.0)));
}
}
void dfs2(int x)
{
int temp;
dd hh;
for(int i=first[x];i!=-1;i=a1[i].next)
{
temp=a1[i].v;
if(temp==fa[x])
continue;
hh=0;
if(deg[x]>1)
hh=(xi[temp]*(1.0/(deg[x]-1.0)));
shr[temp]=( sh[x]+( xi[x]-hh ) )*(1.0/deg[temp]);
if(deg[temp]>1)
sh[temp]=( ( xi[x]-hh )+sh[x] )*(1.0/(deg[temp]-1.0));
dfs2(temp);
}
}
int main(){
//freopen("T2.in","r",stdin);
//freopen("T2.out","w",stdout);
mem(first,-1);
n=read();
for(int i=1;i<=n;++i)
A[i]=read();
int tin1,tin2;
for(int i=1;i<n;++i)
{
tin1=read();tin2=read();
deg[tin1]+=1.0;
deg[tin2]+=1.0;
addbian(tin1,tin2);
addbian(tin2,tin1);
}
dfs1(1);
dfs2(1);
dd mn=shr[1]+xir[1];
int order=1;
for(int i=2;i<=n;++i)
if(mn>shr[i]+xir[i]-esp)
{
mn=shr[i]+xir[i];
order=i;
}
/*printf("
");
for(int i=1;i<=n;++i)
printf("i=%d %lf
",i,shr[i]+xir[i]);
printf("
");
for(int i=1;i<=n;++i)
printf("i=%d %lf
",i,shr[i]);
printf("
");
for(int i=1;i<=n;++i)
printf("i=%d %lf
",i,xir[i]);
printf("
");*/
cout<<order;
}
T3
splay区间翻转
然后并查集维护相同的
在用类似于26进制的方法解(luan)出(gao)
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define ls(x) ((x)->ch[0])
#define p(x) ((x)->p)
#define v(x) ((x)->v)
#define rs(x) ((x)->ch[1])
#define flag(x) ((x)->flag)
#define s(x) ((x)->s)
#define mem(a,b) memset(a,b,sizeof(a))
#define ll long long
using namespace std;
inline int read()
{
char q=getchar();int ans=0;
while(q<'0'||q>'9')q=getchar();
while(q>='0'&&q<='9'){ans=ans*10+q-'0';q=getchar();}
return ans;
}
inline char readchar()
{
char q=getchar();
while( (q<'a'||q>'z')&&q!='?' )q=getchar();
return q;
}
const int N=600006;
const int INF=0x7fffffff;
int n,m;
ll K;
char s[N];
int ji[N],ccc;
struct sp
{
int s,flag,v;
sp *ch[2],*p;
sp(int size,int val,sp *fa)
{
p=fa;s=size;v=val;
flag=0;
}
}*null;
sp* newsp(int size,int val,sp *fa)
{
sp *temp=new sp(size,val,fa);
ls(temp)=rs(temp)=null;
return temp;
}
struct Splay
{
sp *root,*temp;
void sw(sp *x)
{
if(x==null)
return ;
flag(x)^=1;
temp=ls(x);ls(x)=rs(x);rs(x)=temp;
}
void pushdown(sp *x)
{
if(x==null||!flag(x))
return ;
if(ls(x)!=null)sw(ls(x));
if(rs(x)!=null)sw(rs(x));
flag(x)=0;
}
void pushup(sp *x)
{
if(x==null)
return ;
s(x)=s(ls(x))+s(rs(x))+1;
}
inline int islc(sp *x){return ls(p(x))==x;}
void rot(sp *x)
{
sp *y=p(x);int d=islc(x);
pushdown(y);pushdown(x);
if(p(y)==null)root=x;
else p(y)->ch[islc(y)^1]=x;
p(x)=p(y);
y->ch[d^1]=x->ch[d];
if(x->ch[d]!=null)p(x->ch[d])=y;
x->ch[d]=y;p(y)=x;
pushup(y);pushup(x);
}
void splay(sp *x,sp *t)
{
sp *y;
while(p(x)!=t)
{
y=p(x);
if(p(y)!=t){ islc(x)==islc(y)?rot(y):rot(x);}
rot(x);//printf("aaa
");
}
}
sp* kth(int k)
{
sp *x=root;
while(x!=null)
{
//printf("s=%d k=%d
",s(ls(x))+1,k);
pushdown(x);
if( s(ls(x))+1==k )return x;
if( s(ls(x))+1>k )
x=ls(x);
else
{k-=(s(ls(x))+1);x=rs(x);}
}
return null;
}
void change(int l,int r)
{
sp *tt=kth(l);
splay(tt,null);
splay(kth(r+2),root);
sw(ls(rs(root)));//printf("l=%d r=%d
",l,r);
}
sp* build(int l,int r,sp *fa)
{
if(l>r)
return null;
//printf("bl=%d br=%d
",l,r);
int mid=(l+r)>>1;
sp *x=newsp(1,mid,fa);
ls(x)=build(l,mid-1,x);
rs(x)=build(mid+1,r,x);
pushup(x);
return x;
}
void build()
{
root=newsp(1,-INF,null);
rs(root)=newsp(1,INF,root);
ls(rs(root))=build(1,n,rs(root));
pushup(ls(rs(root)));
pushup(rs(root));
pushup(root);
//printf("sizeisss %d
",s(root));
}
void dfs(sp *x)
{
if(x==null)
return ;
//printf("dsf
");
pushdown(x);
dfs(ls(x));
//printf("v=%d
",v(x));
ji[++ccc]=v(x);
dfs(rs(x));
}
void dfs()
{
splay(kth(1),null);
splay(kth(n+2),root);
dfs(ls(rs(root)));
}
}T;
int ff[N];
char vv[N];
int fin(int x)
{
if(ff[x]==-1)
return x;
return ff[x]=fin(ff[x]);
}
inline void match(int u,int v)
{
int x=fin(u),y=fin(v);
if(x==y)
return ;
if(x<y)
{
ff[y]=x;
if(vv[y]!='?')
vv[x]=vv[y];
}
else
{
ff[x]=y;
if(vv[x]!='?')
vv[y]=vv[x];
}
}
int q[N],con;
char qv[N];
char fina[N];
ll mi(ll a,int ci)
{
ll ans=1;
while(ci)
{
if(ci&1)
ans=ans*a;
printf("ci=%d
",ci);
a=a*a;
ci>>=1;
}
return ans;
}
ll tt[N];
void work()
{
for(int i=1;i<=n;++i)
vv[i]=s[i];
/*printf("
");
for(int i=1;i<=ccc;++i)
printf("%d ",ji[i]);
printf("
");*/
for(int i=1;i<=n;++i)
{
match(i,ji[i]);
}
for(int i=1;i<=n;++i)
if(fin(i)==i&&vv[i]=='?')
q[++con]=i;
tt[con+1]=1;
int order=con;
for(int i=con;i>=1;--i)
{
order=i;
if(K/tt[i+1]<26)
break;
tt[i]=tt[i+1]*26;
}
for(int i=1;i<order;++i)
qv[i]='a';
ll temp;
for(int i=order;i<=con;++i)
{
/*if(K<tt[i+1])
{
qv[i]='a';
continue;
}*/
temp=K/tt[i+1];
qv[i]='a'+temp;
if(temp*tt[i+1]==K)
--qv[i];
K-=(temp*tt[i+1]);
}
for(int i=1;i<=con;++i)
vv[q[i]]=qv[i];
for(int i=1;i<=n;++i)
fina[i]=vv[fin(i)];
}
int main(){
//freopen("T3.in","r",stdin);
mem(ff,-1);
null=new sp(0,0,NULL);
ls(null)=rs(null)=NULL;
n=read();m=read();scanf("%lld",&K);
for(int i=1;i<=n;++i)
s[i]=readchar();
T.build();
int l0,r0;
for(int i=1;i<=m;++i)
{
l0=read();r0=read();
T.change(l0,r0);
}
T.dfs();
work();
for(int i=1;i<=n;++i)
printf("%c",fina[i]);
}
总之,昨天晚上的考试 长了教训
还是要相信 T1是最简单的... (其实在打后面题的时候,就隐隐约约有一种感觉是T1很简单,但是也没在意这种感觉)
T1误导我的 其实是n,m的范围... 以后还是要花上10min好好审题啊啊啊
(这感觉就像 你好不容易把地狱领主砍死了,结果剩下一滴血,被小兵A死了)