怎么也过不了的题QAQ
3545: [ONTAK2010]Peaks 写的splay+启发式合并不知为何WA啊QAQ,然而网上都没这么写的。
3083: 遥远的国度 感觉是链剖sb题啊然而就是过不了,submit*20。
1189: [HNOI2007]紧急疏散evacuate 本地测数据全过了,二分网络流傻逼题。交上去WA。
3676: [Apio2014]回文串 正解似乎是manacher。。我不想学。。写的后缀数组在UOJ73分,Subtask#5 TLE了QAQ
贴一份WA代码。。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#define ll long long
using namespace std;
char s[600005];
int l,len,cc[600005],t1[600005],t2[600005];
ll ans=1;
int sa[600005],rank[600005],height[600005],f[600005][20];
inline bool cmp(int *y,int a,int b,int k)
{
int arank1=y[a];
int brank1=y[b];
int arank2=a+k>=l?-1:y[a+k];
int brank2=b+k>=l?-1:y[b+k];
return arank1==brank1&&arank2==brank2;
}
inline void make_sa()
{
int *x=t1,*y=t2;
int m=256;
for (int i=0;i<m;i++) cc[i]=0;
for (int i=0;i<l;i++) ++cc[x[i]=s[i]];
for (int i=1;i<m;i++) cc[i]+=cc[i-1];
for (int i=l-1;~i;i--) sa[--cc[x[i]]]=i;
for (int k=1;k<l;k<<=1)
{
int p=0;
for (int i=l-k;i<l;i++) y[p++]=i;
for (int i=0;i<l;i++)
if (sa[i]>=k) y[p++]=sa[i]-k;
for (int i=0;i<m;i++) cc[i]=0;
for (int i=0;i<l;i++) ++cc[x[y[i]]];
for (int i=1;i<m;i++) cc[i]+=cc[i-1];
for (int i=l-1;~i;i--) sa[--cc[x[y[i]]]]=y[i];
swap(x,y); m=1; x[sa[0]]=0;
for (int i=1;i<l;i++)
x[sa[i]]=cmp(y,sa[i-1],sa[i],k)?m-1:m++;
if (m>=l) break;
}
}
inline void make_height()
{
for (int i=0;i<l;i++) rank[sa[i]]=i;
int k=0; height[0]=0;
for (int i=0;i<l;i++)
{
if (!rank[i]) continue;
int j=sa[rank[i]-1];
if (k) k--;
while (s[j+k]==s[i+k]) k++;
height[rank[i]]=k;
}
}
inline void make_st()
{
for (int i=0;i<l;i++) f[i][0]=height[i];
for (int j=1;j<=19;j++)
for (int i=0;i<l;i++)
if (i+(1<<j)-1<l)
f[i][j]=min(f[i][j-1],f[i+(1<<(j-1))][j-1]);
}
inline int find_min(int l,int r)
{
int t=log2(r-l+1);
return min(f[l][t],f[r-(1<<t)+1][t]);
}
inline int lcp(int l,int r)
{
if (l>r) swap(l,r);
return find_min(l+1,r);
}
inline int ask_pre(int RR,int x)
{
int L=1,R=RR,ans=RR+1;
while (L<=R)
{
int mid=L+R>>1;
if (find_min(mid,RR)>=x) ans=mid,R=mid-1; else L=mid+1;
}
return ans-1;
}
inline int ask_nxt(int LL,int x)
{
int L=LL+1,R=l-1,ans=LL;
while (L<=R)
{
int mid=L+R>>1;
if (find_min(LL+1,mid)>=x) ans=mid,L=mid+1; else R=mid-1;
}
return ans;
}
inline void calc(int pos,int Palindromic_len)
{
int x=rank[pos];
int l,r;
l=ask_pre(x,Palindromic_len);
r=ask_nxt(x,Palindromic_len);
ans=max(ans,(ll)(r-l+1)*(ll)Palindromic_len);
}
inline void find_Palindromic(int pos1,int pos2)
{
int l=rank[pos1],r=rank[pos2];
int Palindromic_len=lcp(l,r);
if (pos1+pos2==2*len) calc(pos1-Palindromic_len+1,Palindromic_len*2-1);
else calc(pos1-Palindromic_len,Palindromic_len*2);
}
int main()
{
scanf("%s",s);
len=strlen(s);
s[len]='&';
for (int i=len+1;i<=2*len;i++) s[i]=s[2*len-i];
l=2*len+1;
make_sa();
make_height();
make_st();
for (int i=0;i<len;i++)
{
find_Palindromic(i,2*len-i);
if (s[i]==s[i-1]) find_Palindromic(i,2*len+1-i);
}
cout << (ans>>1);
return 0;
}
3677: [Apio2014]连珠线 不会做。。写了一个不能再暴力的暴力在UOJ26分。。看起来正解挺麻烦的样子,像一个分情况讨论的恶心DPQAQ。挖坑。。APIO2014看起来只有73+100+26=199了。
贴暴力走人。。
#include<iostream>
#include<cstdio>
#define inf 1000000007
using namespace std;
int n,ans,cnt;
int f[200005][2];
int head[200005],w[200005];
int next[400005],list[400005],key[400005];
inline int read()
{
int a=0,f=1; char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();}
while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();}
return a*f;
}
inline void insert(int x,int y,int z)
{
next[++cnt]=head[x];
head[x]=cnt;
list[cnt]=y;
key[cnt]=z;
}
void dp(int x,int fa)
{
int sumson=0;
f[x][0]=f[x][1]=0;
for (int i=head[x];i;i=next[i])
if (list[i]!=fa)
{
w[list[i]]=key[i];
dp(list[i],x);
sumson++;
}
if (!x) {f[x][1]=-inf; return;}
for (int i=head[x];i;i=next[i])
if (list[i]!=fa)
{
f[x][1]+=max(f[list[i]][1],f[list[i]][0]);
if (fa) f[x][1]=max(f[x][1],f[x][0]+f[list[i]][0]+w[x]+w[list[i]]);
f[x][0]+=max(f[list[i]][1],f[list[i]][0]);
}
}
int main()
{
n=read();
for (int i=1;i<n;i++)
{
int u=read(),v=read(),z=read();
insert(u,v,z); insert(v,u,z);
}
for (int i=1;i<=n;i++)
dp(i,0),ans=max(ans,f[i][0]);
cout << ans;
return 0;
}
4003: [JLOI2015]城池攻占 写的可并堆一直T。。实在不知道怎么回事调不出来,先挂在这吧。。(原题似乎每个点10s就稳稳过了。。)
#include<iostream>
#include<cstdio>
#define ll long long
#define inf 1e19
#define N 300005
using namespace std;
int next[N],list[N],head[N];
int root[N],q[N],id[N],l[N],r[N],d[N],deep[N],a[N],c[N],ans1[N],ans2[N];
ll tag_a[N],tag_t[N],v[N],t[N],h[N];
int n,m,cnt,cnt0;
inline ll read()
{
ll a=0,f=1; char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();}
while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();}
return a*f;
}
inline void insert(int x,int y)
{
next[++cnt0]=head[x];
head[x]=cnt0;
list[cnt0]=y;
}
inline void mul(int x,ll y)
{
tag_a[x]*=y; tag_t[x]*=y; v[x]*=y;
}
inline void add(int x,ll y)
{
tag_a[x]+=y; v[x]+=y;
}
inline void pushdown(int x)
{
if (l[x]) mul(l[x],tag_t[x]);
if (r[x]) mul(r[x],tag_t[x]);
tag_t[x]=1;
if (l[x]) add(l[x],tag_a[x]);
if (r[x]) add(r[x],tag_a[x]);
tag_a[x]=0;
}
inline int merge(int x,int y)
{
if (!x||!y) return x+y;
if (v[x]>v[y]) swap(x,y);
pushdown(x);
r[x]=merge(r[x],y);
if (d[r[x]]>d[l[x]]) swap(l[x],r[x]);
d[x]=d[r[x]]+1;
return x;
}
inline int new_heap(int i,ll val,int s)
{
l[++cnt]=r[cnt]=d[cnt]=0;
v[cnt]=val; id[cnt]=i; c[cnt]=s;
tag_t[cnt]=1; tag_a[cnt]=0;
return cnt;
}
inline int pop(int x)
{
pushdown(x);
return merge(l[x],r[x]);
}
void dfs(int x)
{
for (int i=head[x];i;i=next[i])
{
deep[list[i]]=deep[x]+1;
dfs(list[i]);
root[x]=merge(root[x],root[list[i]]);
}
while (v[root[x]]<h[x]&&root[x])
{
ans1[x]++; ans2[id[root[x]]]=deep[c[root[x]]]-deep[x];
root[x]=pop(root[x]);
}
if (root[x])
{
if (a[x]) mul(root[x],t[x]); else add(root[x],t[x]);
}
}
inline void work(int x)
{
for (int i=head[x];i;i=next[i])
root[x]=merge(root[x],root[list[i]]);
while (root[x]&&v[root[x]]<h[x])
{
ans1[x]++; ans2[id[root[x]]]=deep[c[id[root[x]]]]-deep[x];
root[x]=pop(root[x]);
}
if (root[x])
{
if (a[x]) mul(root[x],t[x]); else add(root[x],t[x]);
}
}
inline void bfs()
{
int t=0,w=1;
q[1]=1;
while (t<w)
{
int x=q[++t];
for (int i=head[x];i;i=next[i])
{
deep[list[i]]=deep[x]+1;
q[++w]=list[i];
}
}
for (int i=n;i;i--) work(q[i]);
}
int main()
{
// freopen("fall.in","r",stdin);
// freopen("fall.out","w",stdout);
n=read(); m=read();
for (int i=1;i<=n;i++) h[i]=read();
for (int i=2;i<=n;i++)
{
int f=read(); a[i]=read(); t[i]=read();
insert(f,i);
}
for (int i=1;i<=m;i++)
{
int v=read(),s=read();
root[s]=merge(root[s],new_heap(i,v,s));
}
bfs();
// dfs(1);
while (root[1])
{
ans2[id[root[1]]]=deep[c[root[1]]]+1;
root[1]=pop(root[1]);
}
for (int i=1;i<=n;i++) printf("%d\n",ans1[i]);
for (int i=1;i<=m;i++) printf("%d\n",ans2[i]);
return 0;
}
3932: [CQOI2015]任务查询系统 主席树维护前缀和,本地测试80分不知道怎么改了。。
#include<iostream>
#include<cstdio>
#include<algorithm>
#define ll long long
#define N 5000005
using namespace std;
int n,m,sz,cnt;
ll ans;
int ls[N],rs[N],size[N];
ll sum[N];
int hash[100005],ys[100005],root[200005];
struct node {int s,t,p;} a[100005];
struct data {int x,v,p;} c[200005];
inline int read()
{
int a=0,f=1; char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();}
while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();}
return a*f;
}
inline bool cmp(node a,node b)
{
return a.p<b.p;
}
inline bool cmp0(data a,data b)
{
return a.x<b.x;
}
inline int find(int x)
{
int l=1,r=cnt;
while (l<=r)
{
int mid=l+r>>1;
if (hash[mid]==x) return mid;
else if (hash[mid]<x) l=mid+1;
else r=mid-1;
}
}
void update(int l,int r,int x,int &y,int t,int v)
{
y=++sz;
size[y]=size[x]+v;
if (l==r) {sum[y]=sum[x]+hash[t]*v; return;}
ls[y]=ls[x]; rs[y]=rs[x];
int mid=l+r>>1;
if (t<=mid) update(l,mid,ls[x],ls[y],t,v);
else update(mid+1,r,rs[x],rs[y],t,v);
sum[y]=sum[ls[y]]+sum[rs[y]];
}
ll query(int l,int r,int x,int k)
{
int mid=l+r>>1;
if (l==r) return sum[x];
if (k==size[x]) return sum[x];
else if (k<=size[ls[x]]) return query(l,mid,ls[x],k);
else return sum[ls[x]]+query(mid+1,r,rs[x],k-size[ls[x]]);
}
int main()
{
// freopen("query.in","r",stdin);
// freopen("query.out","w",stdout);
m=read(); n=read();
for (int i=1;i<=m;i++)
a[i].s=read(),a[i].t=read(),a[i].p=read();
sort(a+1,a+m+1,cmp);
hash[++cnt]=a[1].p;
for (int i=2;i<=m;i++)
if (a[i].p!=a[i-1].p) hash[++cnt]=a[i].p;
for (int i=1;i<=m;i++)
{
c[2*i-1].x=a[i].s; c[2*i-1].v=1; c[2*i-1].p=a[i].p;
c[2*i].x=a[i].t+1; c[2*i].v=-1; c[2*i].p=a[i].p;
}
sort(c+1,c+2*m+1,cmp0);
for (int i=1;i<=(m<<1);i++)
{
int t=find(c[i].p);
update(1,cnt,root[i-1],root[i],t,c[i].v);
ys[c[i].x]=i;
}
for (int i=1;i<=2*m;i++)
for (int j=c[i].x+1;j<c[i+1].x;j++)
ys[j]=ys[c[i].x];
ans=1;
for (int i=1;i<=n;i++)
{
int x=read(),a=read(),b=read(),c=read(),k=1+(ans*a+b)%c;
if (k>size[root[ys[x]]]) ans=sum[root[ys[x]]];
else ans=query(1,cnt,root[ys[x]],k);
printf("%lld\n",ans);
}
return 0;
}
4337: BJOI2015 树的同构 开始自己YY了一个,先找到直径,然后转化为链上的hash,结果死活不对。。于是看了Creation[Au]gust的题解明白了标算。。结果又死活调不出来。。于是我就弃疗了。
开始自己写的WA代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define base0 177
#define base 233
#define ll long long
using namespace std;
int m,now_left;
struct node {ll v;int id;} hash[55];
int ans[55];
inline int read()
{
int a=0,f=1; char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();}
while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();}
return a*f;
}
struct tree
{
int n,cnt,S,T,top;
int head[55],list[105],next[105];
int q[55],dis[55],from[55],mark[55],stack[55];
ll sum[55];
inline void insert(int x,int y)
{
next[++cnt]=head[x];
head[x]=cnt;
list[cnt]=y;
}
inline void BFS(int s)
{
memset(dis,-1,sizeof(dis));
int t=0,w=1,x;
q[1]=s; dis[s]=0;
while (t<w)
{
x=q[++t];
for (int i=head[x];i;i=next[i])
if (dis[list[i]]==-1)
{
from[list[i]]=x;
dis[list[i]]=dis[x]+1;
q[++w]=list[i];
}
}
}
inline void find_max_length_road()
{
BFS(1);
for (int i=1;i<=n;i++) if (dis[i]>dis[S]) S=i;
from[S]=0;
BFS(S);
for (int i=1;i<=n;i++) if (dis[i]>dis[T]) T=i;
}
ll calc(int x,ll deep,int fa)
{
ll now=deep;
for (int i=head[x];i;i=next[i])
if (list[i]!=fa) now+=calc(list[i],deep+1,x)*base0;
return now;
}
inline void pre()
{
for (int i=T;i;i=from[i]) stack[++top]=i;
for (int i=1;i<=top;i++) mark[stack[i]]=1;
for (int i=1;i<=top;i++)
for (int j=head[stack[i]];j;j=next[j])
if (!mark[list[j]]) sum[stack[i]]+=calc(list[j],1,stack[i])*base0;
}
inline ll get_hash()
{
ll t1=0,t2=0;
for (int i=1;i<=top;i++) t1=t1*base+sum[stack[i]];
for (int i=top;i;i--) t2=t2*base+sum[stack[i]];
return min(t1,t2);
}
};
tree f[55];
inline bool cmp(node a,node b)
{
return f[a.id].n==f[b.id].n?(a.v==b.v?a.id<b.id:a.v<b.v):f[a.id].n<f[b.id].n;
}
int main()
{
m=read();
for (int i=1;i<=m;i++)
{
f[i].n=read();
for (int j=1;j<=f[i].n;j++)
{
int fa=read();
if (fa) f[i].insert(fa,j),f[i].insert(j,fa);
}
}
for (int i=1;i<=m;i++) f[i].find_max_length_road();
for (int i=1;i<=m;i++) f[i].pre();
for (int i=1;i<=m;i++) hash[i].id=i,hash[i].v=f[i].get_hash();
sort(hash+1,hash+m+1,cmp);
ans[hash[1].id]=hash[1].id;
now_left=hash[1].id;
for (int i=2;i<=m;i++)
{
if (hash[i].v!=hash[i-1].v||f[hash[i].id].n!=f[hash[i].id].n) now_left=hash[i].id;
ans[hash[i].id]=now_left;
}
for (int i=1;i<=m;i++) printf("%d\n",ans[i]);
return 0;
}
调不出来的标算
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll unsigned
using namespace std;
int n,m,cnt;
int ct[120],head[120],list[120],next[120];
ll sum[120],stack[120],hash[120][120];
ll base[100]={0,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317};
inline int read()
{
int a=0,f=1; char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();}
while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();}
return a*f;
}
inline void insert(int x,int y)
{
next[++cnt]=head[x];
head[x]=cnt;
list[cnt]=y;
}
void get_hash(int x,int fa)
{
ll top=0; stack[++top]=1;
for (int i=head[x];i;i=next[i])
if (list[i]!=fa) get_hash(list[i],x),stack[++top]=sum[list[i]];
sort(stack+1,stack+top+1); sum[x]=0;
for (int i=1;i<=top;i++) sum[x]+=stack[i]*base[i];
}
int main()
{
m=read();
for (int k=1;k<=m;k++)
{
n=ct[k]=read();
memset(head,0,sizeof(head));
cnt=0;
for (int i=1;i<=n;i++)
{
int fa=read();
if (fa) insert(i,fa),insert(fa,i);
}
for (int i=1;i<=n;i++) get_hash(i,0),hash[k][i]=sum[i];
sort(hash[k]+1,hash[k]+n+1);
for (int i=1;i<=k;i++)
if (ct[i]==n)
{
int j=1;
for (;j<=n;j++)
if (hash[i][j]!=hash[k][j]) break;
if (j>n) {printf("%d\n",i); break;}
}
}
return 0;
}