T1 字符串
$Catalan$数裸题,非常裸。
公式$C_{n+m}^m-C_{n+m}^{m-1}$。
做了俩小时,真傻逼。
T2 乌鸦喝水
不会做,思路挺好想,但是不好实现。
最重要的一点:TM看题看错了!!
排一下序,用树状数组维护其前缀和,然后挨个处理就好。
小弟不才。
1 #include<cstdio> 2 #include<algorithm> 3 #define LL long long 4 #define HZOI std 5 using namespace HZOI; 6 const int N=5e7+3; 7 struct node{ 8 LL w,a,c,id; 9 friend bool operator < (node a,node b) 10 { 11 return a.c<b.c; 12 } 13 }t[N]; 14 LL n,m,k; 15 LL num,cnt; 16 LL ans,lst; 17 LL sz[N]; 18 inline LL read(); 19 inline LL Ask(LL ); 20 inline void Add(LL ,LL ); 21 int main() 22 { 23 n=read(),m=read(),k=read(); 24 for (int i=1; i<=n; ++i) t[i].w=read(),t[i].id=i; 25 for (int i=1; i<=n; ++i) t[i].a=read(); 26 for (int i=1; i<=n; ++i) t[i].c=(k-t[i].w)/t[i].a+1,Add(i,1); 27 sort(t+1,t+n+1); 28 for (int i=1; i<=n; ++i) 29 { 30 LL l=0,r=m; 31 while (l^r) 32 { 33 int mid=(l+r>>1)+1; 34 if ((n-i+1)*mid+lst>=t[i].c) r=mid-1; 35 else l=mid; 36 } 37 if (cnt+l>=m) { ans+=(n-i+1)*1ll*m; break; } 38 num=l+cnt; 39 if (Ask(t[i].id)+lst+(n-i+1)*1ll*l<=t[i].c) ++lst,++num; 40 lst+=l*1ll*(n-i+1); cnt+=l; 41 ans+=num; 42 Add(t[i].id,-1); 43 } 44 printf("%lld ",ans); 45 } 46 inline LL Ask(LL x) 47 { 48 LL res=0; 49 while (x) 50 { 51 res+=sz[x]; 52 x-=x&-x; 53 } 54 return res; 55 } 56 inline void Add(LL x,LL data) 57 { 58 while (x<=n) 59 { 60 sz[x]+=data; 61 x+=x&-x; 62 } 63 } 64 inline LL read() 65 { 66 LL nn=0; char cc=getchar(); 67 while (cc<'0' || cc>'9') cc=getchar(); 68 while (cc>='0' && cc<='9') nn=(nn<<3)+(nn<<1)+(cc^48),cc=getchar(); 69 return nn; 70 }
T3 所驼门王的宝藏
这道题说难也难,说简单也挺简单。
其实就是数据出的太水了。
本人用的思路简单的$vector$$+$$map$,但$map$太慢了容易被卡,但是我还是没有抵制住map强大功能的诱惑,但$A$了之后发现数据真的水。
思路:给能到达的点连上有向边,然后跑$Tarjan$缩点,最后拓扑序$dp$求最长链(权值最大的一条链,权值是这个方点内的点数)。
挺好想的,不过调也得半天。
然而考试的时候我弃了。
小弟不才。
1 #include<cstdio> 2 #include<cstring> 3 #include<map> 4 #include<vector> 5 #define HZOI std 6 using namespace HZOI; 7 const int ju=2e6+3; 8 const int P=2e6+3; 9 struct node{ 10 int x,y,z; 11 }poi[P]; 12 struct EDGE{ 13 int v,nx; 14 }edge[P<<1]; 15 int n,r,c,ans,res; 16 int tail,tot,cnt,dfn[P],low[P],stc[P],vis[P],be[P],w[P]; 17 int tt,first[P],vv[P<<1],nx[P<<1]; 18 int head,t,Nfirst[P],du[P],dp[P],que[P]; 19 vector<int> hang[ju],lie[ju]; 20 map<pair<int ,int >,int> mp; 21 int dx[8]={0,0,1,1,1,-1,-1,-1},dy[8]={1,-1,1,-1,0,0,1,-1}; 22 void Tarjan(int ); 23 void Bfs(); 24 inline void Add(int ,int ); 25 inline void NAdd(int ,int ); 26 inline int read(); 27 int main() 28 { 29 n=read(),r=read(),c=read(); 30 for (int i=1; i<=n; ++i) 31 poi[i].x=read(),poi[i].y=read(),poi[i].z=read(),hang[poi[i].x].push_back(i),lie[poi[i].y].push_back(i),mp[make_pair(poi[i].x,poi[i].y)]=i; 32 for (int i=1; i<=n; ++i) 33 { 34 int x=poi[i].x,y=poi[i].y; 35 if (poi[i].z==1) 36 { 37 int siz=hang[x].size(); 38 for (int j=0; j<siz; ++j) 39 if (hang[x][j]!=i) 40 Add(i,hang[x][j]); 41 } 42 if (poi[i].z==2) 43 { 44 int siz=lie[y].size(); 45 for (int j=0; j<siz; ++j) 46 if (lie[y][j]!=i) 47 Add(i,lie[y][j]); 48 } 49 if (poi[i].z==3) 50 { 51 for (int j=0; j<8; ++j) 52 if (mp[make_pair(x+dx[j],y+dy[j])]>0) 53 Add(i,mp[make_pair(x+dx[j],y+dy[j])]); 54 } 55 } 56 for (int i=1; i<=n; ++i) 57 if (!dfn[i]) Tarjan(i); 58 for (int i=1; i<=n; ++i) 59 for (int j=first[i]; j; j=nx[j]) 60 if (be[vv[j]]!=be[i]) 61 NAdd(be[i],be[vv[j]]),++du[be[vv[j]]]; 62 tail=head=0; 63 for (int i=1; i<=cnt; ++i) 64 if (!du[i]) dp[i]=w[i],que[++tail]=i; 65 Bfs(); 66 printf("%d ",ans); 67 } 68 void Bfs() 69 { 70 while (head^tail) 71 { 72 int x=que[++head]; 73 for (int i=Nfirst[x]; i; i=edge[i].nx) 74 { 75 int ver=edge[i].v; 76 if (du[ver]<=0) continue; 77 dp[ver]=max(dp[ver],dp[x]+w[ver]); 78 if ((--du[ver])<=0) 79 que[++tail]=ver; 80 } 81 ans=max(dp[x],ans); 82 } 83 } 84 void Tarjan(int k) 85 { 86 dfn[k]=low[k]=++tot; 87 stc[++tail]=k; 88 vis[k]=1; 89 for (int i=first[k]; i; i=nx[i]) 90 { 91 int ver=vv[i]; 92 if (!dfn[ver]) 93 { 94 Tarjan(ver); 95 low[k]=min(low[ver],low[k]); 96 } 97 if (vis[ver]) low[k]=min(low[k],dfn[ver]); 98 } 99 if (dfn[k]==low[k]) 100 { 101 int to; ++cnt; 102 do 103 { 104 to=stc[tail--]; 105 be[to]=cnt; 106 vis[to]=0; 107 ++w[cnt]; 108 }while (to!=k); 109 } 110 } 111 inline void NAdd(int u,int v) 112 { 113 edge[++t].v=v,edge[t].nx=Nfirst[u],Nfirst[u]=t; 114 } 115 inline void Add(int u,int v) 116 { 117 vv[++tt]=v,nx[tt]=first[u],first[u]=tt; 118 } 119 inline int read() 120 { 121 int nn=0; char cc=getchar(); 122 while (cc<'0' || cc>'9') cc=getchar(); 123 while (cc>='0' && cc<='9') nn=(nn<<3)+(nn<<1)+(cc^48),cc=getchar(); 124 return nn; 125 }