2017.10.2 loli测试

来源:互联网 发布:artrage mac破解 编辑:程序博客网 时间:2024/05/23 10:19

T1+T2 200  T3惨遭爆零



所有回文串都是中心对称的,所以只要不存在长度为2的和长度为3的即可

排列组合可知

ans=(m)*(m-1)*(m-2)^(n-2)

码:

#include<iostream>#include<cstdio>using namespace std;#define ll long long#define P 1000000007 ll T,n,m;ll ksm(ll a,ll b){ll ans=1;while(b){if(b%2)ans=(ans*a)%P;b/=2;a=(a*a)%P;}return ans;}int main(){freopen("anti.in","r",stdin);freopen("anti.out","w",stdout);scanf("%lld",&T);while(T--){scanf("%lld%lld",&n,&m);if(n==1){printf("%lld\n",m%P);continue;    }if(n==2){printf("%lld\n",(m%P)*((m-1)%P)%P);continue;    }printf("%lld\n",(m%P)*((m-1)%P)%P*ksm((m-2)%P,n-2 )%P);}}


如果对一个节点求,就是裸的树形dp,,

通过前一次的答案对后一次答案的重复部分,可以化简下一个节点的答案

所以相邻节点间的转移是O(1)的


码:

#include<iostream>#include<cstdio>#include<cstring>#define eps 0.000000005using namespace std;double f[1000005],ans=10000000000000009;int from,i,n,m,a,b,ru[1000005],v[1000005],fu[1000005],tot,xia[1000005],hou[2000005],zhong[2000005];void jian(int a,int b){++tot;hou[tot]=xia[a],xia[a]=tot,zhong[tot]=b;}void jia(int a,int b){jian(a,b);jian(b,a);}void dfs(int o,int fa){int i;fu[o]=fa;f[o]=v[o];for(i=xia[o];i!=-1;i=hou[i]){int nd=zhong[i];if(nd==fa)continue;dfs(nd,o);if(o==1){f[o]+=f[nd]*(1.0/ru[o]);}else{f[o]+=f[nd]*(1.0/(ru[o]-1));    } }}void dfs2(int o)//统计贡献 {if(o==1){ans=f[o];from=o;}else{double qita=f[fu[o]]-f[o]*1/ru[fu[o]];//从上面的点下来的子树去掉if((ru[fu[o]]-1)==0)f[o]=1.0*v[o]  +  1.0*(f[o]-v[o])*(ru[o]-1)/ru[o]   +  1.0*v[fu[o]]*1/ru[o]; else f[o]=1.0*v[o]  +  1.0*(f[o]-v[o])*(ru[o]-1)/ru[o]   +  1.0*(v[fu[o]] + (qita-v[fu[o]])*ru[fu[o]]/(ru[fu[o]]-1))*1/ru[o]; if(ans+eps>=f[o]&&ans-eps<=f[o]){from=min(from,o);}if(ans-eps>f[o]){ans=f[o];from=o;}}int i;for(i=xia[o];i!=-1;i=hou[i]){int nd=zhong[i];if(nd==fu[o])continue;   dfs2(nd);}}int main(){freopen("walking.in","r",stdin);freopen("walking.out","w",stdout);memset(xia,-1,sizeof(xia));scanf("%d",&n);for(i=1;i<=n;i++){scanf("%d",&v[i]);}for(i=1;i<n;i++)     {     scanf("%d%d",&a,&b);     jia(a,b);     ru[a]++;     ru[b]++; }dfs(1,0);dfs2(1);printf("%d",from);}








。。第三题   第一位没特判 + 加数的时候直接在splay最后加。。所以链非常长,就爆栈了


可以写splay+并查集 暴力堆叠,,但常数爆炸,而这个题卡你常数,,所以需要优化(指针据说可以过)


码(卡常80):

#include<iostream>#include<cstdio>#include<algorithm>using namespace std;#define N 1000006int ch[N][2],fu[N];  int v[N],maz[N],siz[N],may[N],ma[N],fa[N],fg[N],sz[N],fz[N],rt,i,l,r,hou[N],lin,n,m,jilu[N],cnt,nn[N];  bool rev[N],cx[N];  char str[N];long long k;int find(int o){if(o!=fa[o])fa[o]=find(fa[o]);return fa[o];}void up(int o)  {      int l=ch[o][0];      int r=ch[o][1];      sz[o]=sz[l]+sz[r]+1; }  void down(int o)  {      int l=ch[o][0];      int r=ch[o][1];      if(rev[o])      {          rev[o]^=1;rev[l]^=1;rev[r]^=1;          swap(maz[l],may[l]);swap(maz[r],may[r]);          swap(ch[l][0],ch[l][1]);swap(ch[r][0],ch[r][1]);              }          }  int getwh(int o)    {        return ch[fu[o]][0]==o?0:1;    }    void set(int o,int wh,int child)    {        ch[o][wh]=child;        if(child!=0)fu[child]=o;        up(o);    }    void rotate(int o)    {   //cout<<o<<endl;down(o);        int fa=fu[o];        int ye=fu[fu[o]];        int wh=getwh(o);        set(fa,wh,ch[o][wh^1]);        set(o,wh^1,fa);            fu[o]=ye;            if(ye!=0)ch[ye][ch[ye][0]==fa?0:1]=o;    }    void splay(int o,int tar)    {        for(;fu[o]!=tar;rotate(o))        if(fu[fu[o]]!=tar)        getwh(o)==getwh(fu[o])?rotate(fu[o]):rotate(o);         if(tar==0)rt=o;    }    int find(int o,int wz)  { //cout<<sz[o]<<" "<<wz<<endl;    down(o);      int l=ch[o][0],r=ch[o][1];      if(sz[l]+1==wz)return o;      if(sz[l]>=wz)return find(l,wz);      return find(r,wz-sz[l]-1);  }  int xz(int x,int y)  {      int l=find(rt,x),r=find(rt,x+y+1);      splay(l,0);splay(r,rt);      return ch[r][0];  }  void faz(int l,int r)  {  //cout<<l<<" "<<r<<endl;    int o=xz(l,r),fa=fu[o];      if(!fg[o])      {          rev[o]^=1;          swap(ch[o][0],ch[o][1]);          swap(may[o],maz[o]);          up(fa);up(fu[fa]);     }  }  void ins(int l,int r)  {  int mid=(l+r)>>1;sz[mid]=1;if((mid-1-l)>=0){ins(l,mid-1);ch[mid][0]=(l+mid-1)>>1;fu[(l+mid-1)>>1]=mid;}if((r-mid-1)>=0){ins(mid+1,r);ch[mid][1]=(r+mid+1)>>1;fu[(r+mid+1)>>1]=mid;}up(mid);}void dfs(int o){down(o);if(ch[o][0]){dfs(ch[o][0]);}   if(o!=1&&o!=n+2)hou[++lin]=o;   if(ch[o][1]){dfs(ch[o][1]);}}int main(){freopen("string.in","r",stdin);freopen("string.out","w",stdout);lin=1;scanf("%d%d%lld",&n,&m,&k);//cout<<n;scanf("%s",str+2);//从2开始 rt=(1+n+2)>>1;ins(1,n+2);//偏移+1 for(i=1;i<=m;i++){scanf("%d%d",&l,&r);faz(l,r-l+1);//if(i==m/2)cout<<"p";}//cout<<"pp";dfs(rt);for(i=1;i<=n+1;i++)fa[i]=i,sz[i]=1;for(i=2;i<=n+1;i++){//cout<<hou[i]<<" ";if(str[i]=='?'&&str[hou[i]]!='?'){str[find(i)]=str[hou[i]];}if(str[i]!='?'&&str[hou[i]]=='?'){str[find(hou[i])]=str[i];}if(str[i]=='?'&&str[hou[i]]=='?'){int ffa=find(i);int ffb=find(hou[i]);if(ffa==ffb)continue;if(siz[ffa]<siz[ffb])swap(ffa,ffb); fa[ffa]=ffb;if(str[ffa]!='?'){str[ffb]=str[ffa];}siz[ffb]+=siz[ffa];}}for(i=2;i<=n+1;i++){if(str[find(i)]=='?'&&cx[find(i)]==0){cx[fa[i]]=1;jilu[++cnt]=fa[i];}}//cout<<cnt<<endl;int now=26;for(i=1;i<=cnt;i++)str[jilu[i]]='a';lin=0;while(k){nn[++lin]=k%now;if(lin!=1)nn[lin]++;k/=26;}for(i=1;i<=lin;i++){{ str[jilu[cnt-i+1]]='a'+nn[i]-1;//cout<<'a'<<" "<<nn[i]-1<<endl;}}for(i=2;i<=n+1;i++)printf("%c",str[find(i)]);}





原创粉丝点击