「训练日志19」 6.18 坚持自己

T1 字符串

  $Catalan$数裸题,非常裸。

  公式$C_{n+m}^m-C_{n+m}^{m-1}$。

  做了俩小时,真傻逼。

 

T2 乌鸦喝水

  不会做,思路挺好想,但是不好实现。

  最重要的一点:TM看题看错了!!

  排一下序,用树状数组维护其前缀和,然后挨个处理就好。

  小弟不才。

 

 1 #include
 2 #include
 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\n",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
  2 #include
  3 #include
  4 #include
  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 mapint ,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; jj)
 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; jj)
 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\n",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 }
所驼门王的宝藏

 

 

 

你可能感兴趣的:(「训练日志19」 6.18 坚持自己)