Problem1 Preokret

第一题一定不是什么难题。

第一个问题在读入的时候判断当前时间是不是在1440及以前就行

第二个问题考虑离线处理,由于每个时刻只能最多发生1个事件那么就弄个桶记录每一个事件就行了。

水过T1。

Code:

  1. # include <bits/stdc++.h>
  2. using namespace std;
  3. const int N=;
  4. int a[N];
  5. int A,B,T,rec1,rec2;
  6. template <typename T>inline void read(T &x)
  7. {
  8. int w=,X=; char c=;
  9. while (c<''||c>'') w|=c=='-',c=getchar();
  10. while (c>=''&&c<='') X=(X<<)+(X<<)+(c^),c=getchar();
  11. x=w?-X:X;
  12. }
  13. int main()
  14. {
  15. // freopen("Preokret.in","r",stdin);
  16. // freopen("Preokret.out","w",stdout);
  17. memset(a,-,sizeof(a));
  18. read(A);
  19. for (int i=;i<=A;i++) read(T),a[T]=;
  20. read(B);
  21. for (int i=;i<=B;i++) read(T),a[T]=;
  22. int Ans1=,Ans2=,flag=-,s1=,s2=;
  23. for (int i=;i<=;i++) {
  24. if (a[i]==-) continue;
  25. if (a[i]==) s1++; else s2++;
  26. if (i<=) Ans1++;
  27. if (flag==-) { flag=s1<s2; continue;}
  28. if (s1>s2&&flag==) flag=,Ans2++;
  29. else if (s1<s2&&flag==) flag=,Ans2++;
  30. }
  31. cout<<Ans1<<'\n'<<Ans2<<'\n';
  32. return ;
  33. }

Problem2 Kocka

这个题对于100%的数据一定不是O(n2)的构造,而是数学的判断。

我们可以简单考虑四种情况,我们记四个数组分别是left[],right[],up[],down[],

分别考虑四个数组元素值是x的时候代表什么含义,

以left[i]为例,left[i]=-1的时候表示第i行没有放东西,那么对应的right[i]必须也是-1否则构造不合法,而对于up[]和down[]无影响。

left[i]=x(x≠-1时),那么意味着在(i,x+1)这个位置必须存在一个障碍物,那么从上面看下来可以看到的不能大于i-1吧,下面看上来不能超过n-i吧,右边看过来不能超过n-x-1吧。

对于 right[]和up[]和down[]同理。

这里需要注意在C++中up什么的可能是保留字,我Define了一下。

Code

  1. # include <bits/stdc++.h>
  2. # define fp(i,s,t) for (int i=s;i<=t;i++)
  3. # define left Left
  4. # define right Right
  5. # define up Up
  6. # define down Down
  7. using namespace std;
  8. const int N=1e5+;
  9. int left[N],right[N],up[N],down[N],n;
  10. inline void read(int &x)
  11. {
  12. int w=,X=; char c=;
  13. while (c<''||c>'') w|=c=='-',c=getchar();
  14. while (c>=''&&c<='') X=(X<<)+(X<<)+(c^),c=getchar();
  15. x=w?-X:X;
  16. }
  17. bool work()
  18. {
  19. fp(i,,n) {
  20. if (left[i]==-) {
  21. if (right[i]==-) continue;
  22. return ;
  23. }
  24. if (up[left[i]+]==-||up[left[i]+]>i-) return ;
  25. if (down[left[i]+]==-||down[left[i]+]>n-i) return ;
  26. if (right[i]==-||right[i]>n-left[i]-) return ;
  27. }
  28. fp(i,,n) {
  29. if (up[i]==-) {
  30. if (up[i]==-) continue;
  31. return ;
  32. }
  33. if (left[up[i]+]==-||left[up[i]+]>i-) return ;
  34. if (right[up[i]+]==-||right[up[i]+]>n-i) return ;
  35. if (down[i]==-||down[i]>n-up[i]-) return ;
  36. }
  37. fp(i,,n) {
  38. if (right[i]==-) {
  39. if (left[i]==-) continue;
  40. return ;
  41. }
  42. if (up[n-right[i]]==-||up[n-right[i]]>i-) return ;
  43. if (down[n-right[i]]==-||down[n-right[i]]>n-i) return ;
  44. if (left[i]==-||left[i]>n-right[i]-) return ;
  45. }
  46. fp(i,,n) {
  47. if (down[i]==-) {
  48. if (up[i]==-) continue;
  49. return ;
  50. }
  51. if (left[n-down[i]]==-||left[n-down[i]]>i-) return ;
  52. if (right[n-down[i]]==-||right[n-down[i]]>n-i) return ;
  53. if (up[i]==-||up[i]>n-down[i]-) return ;
  54. }
  55. return ;
  56. }
  57. int main()
  58. {
  59. // freopen("Kocka.in","r",stdin);
  60. // freopen("Kocka.out","w",stdout);
  61. read(n);
  62. fp(i,,n) read(left[i]);
  63. fp(i,,n) read(right[i]);
  64. fp(i,,n) read(up[i]);
  65. fp(i,,n) read(down[i]);
  66. puts(work()?"DA":"NE");
  67. return ;
  68. }

Problem3 Deblo

这个题是树上路径计数,初步搞搞O(n2log2 n)暴力还是搞得来的。

但是书上路径统计想到了淀粉质点分治暴力统计路径。

这里需要注意点分治的一般步骤:

每次在子树里面选定一个重心,考虑一条过重心的路径,统计这条边上的异或值。

这里用到异或的一个性质x xor y xor y=x,考虑以子树的根(不一定是重心)dfs下去找到根的xor前缀和

统计每个点的xor,那么就把01塞到桶里面就行了。

注意这个时候由于每一条路径一定过重心所以先把重心加入,其他的前缀和先xor一个重心,这样可以把重心的影响减去。

尤其注意先找这个点和其他点之间xor值然后再更新桶里面的值。

重心打标及时啊!一塞入就打标。

一开始先找重心可以快一点。。。

具体的可以看我的点分治blog例题1:https://www.cnblogs.com/ljc20020730/p/10347198.html

  1. # include <bits/stdc++.h>
  2. # define LL long long
  3. # define fp(i,s,t) for (int i=s;i<=t;i++)
  4. using namespace std;
  5. const int N=1e5+;
  6. const int MAXBIT=;
  7. bool used[N];
  8. int size[N],val[N],cnt[][MAXBIT],n;
  9. struct rec{int pre,to;}a[*N];
  10. int tot,head[N];
  11. template <typename T>inline void read(T& t)
  12. {
  13. char c=getchar();t=;
  14. while(c<''||c>'')c=getchar();
  15. while(c>=''&&c<='')t=(t<<)+(t<<)+(c^),c=getchar();
  16. }
  17. template <typename T,typename... Args> inline void read(T& t, Args&... args)
  18. {
  19. read(t);read(args...);
  20. }
  21. void write(LL x)
  22. {
  23. if (x>) write(x/);
  24. putchar(''+x%);
  25. }
  26. void writeln(LL x)
  27. {
  28. write(x);putchar('\n');
  29. }
  30. void adde(int u,int v)
  31. {
  32. a[++tot].pre=head[u];
  33. a[tot].to=v;
  34. head[u]=tot;
  35. }
  36. int Get_Root(int u,int fath,int S)
  37. {
  38. int pos=;
  39. for (int i=head[u];i;i=a[i].pre) {
  40. int v=a[i].to;
  41. if (v==fath||used[v]) continue;
  42. if (size[v]>size[pos]) pos=v;
  43. }
  44. if (pos!=&&size[pos]>=S/) return Get_Root(pos,u,S);
  45. return u;
  46. }
  47. void Get_Dist(int u,int fath,int num)
  48. {
  49. num^=val[u]; size[u]=;
  50. fp(i,,MAXBIT-)
  51. cnt[(num & (<<i))>][i]++;
  52.  
  53. for (int i=head[u];i;i=a[i].pre){
  54. int v=a[i].to;
  55. if (v==fath||used[v]) continue;
  56. Get_Dist(v,u,num);
  57. size[u]+=size[v];
  58. }
  59. }
  60. LL ans=;
  61. void Get_Ans(int u,int fath,int num)
  62. {
  63. num^=val[u];
  64. fp(i,,MAXBIT-)
  65. ans+=(LL) (<<i)*cnt[(num & (<<i))==][i];
  66. for (int i=head[u];i;i=a[i].pre){
  67. int v=a[i].to;
  68. if (v==fath||used[v]) continue;
  69. Get_Ans(v,u,num);
  70. }
  71. }
  72. void solve(int u,int fath)
  73. {
  74. int root=Get_Root(u,fath,size[u]);
  75. used[root]=;
  76. memset(cnt,,sizeof(cnt));
  77. fp(i,,MAXBIT-)
  78. cnt[(val[root] & (<<i))>][i]++;
  79. ans+=(LL)val[root];
  80. for (int i=head[root];i;i=a[i].pre) {
  81. int v=a[i].to;
  82. if (used[v]) continue;
  83. Get_Ans(v,,);
  84. Get_Dist(v,,val[root]);
  85. }
  86. for (int i=head[root];i;i=a[i].pre) {
  87. int v=a[i].to;
  88. if (used[v]) continue;
  89. solve(v,u);
  90. }
  91. }
  92. int main()
  93. {
  94. read(n); fp(i,,n) read(val[i]);
  95. int u,v;
  96. fp(i,,n-)
  97. read(u,v),adde(u,v),adde(v,u);
  98. int rt=Get_Root(,,n);
  99. Get_Dist(rt,,); solve(rt,);
  100. writeln(ans);
  101. return ;
  102. }

Problem4 Maja

数据加强的三个点其实就是把大多数标程卡掉的点。

就是K不是偶数而是奇数的时候显然是不存在合法的一条路径的。

这点原题中没有说需要判断。(但是神奇的是没有卡WTF)

这道题显然K这么大不是搜索而是DP,

搜索的复杂度O(4K)太大了吧!!! 而且每个点不止重复走1次。

考虑一条性质:假设从原点(A,B)走到(i,j)恰好走了K/2步然后必然会选择走回去是最优的吧。

这个显然。

然后考虑全局的最优,答案一定是一个循环组成的,就是不停地在某一条路上来回走。

这个也是显然的吧。

那么有余数怎么办?可以证明贪心的选取中点四周的一个Ci,j最大的来回走完余数就是这个点最优的。

这个可以反证? 简单yy一下如果不这样选取那么你还不如走到你最终的中点继续循环呢!

然后就是一个DP+贪心的神仙题目了。

先K/=2,只考虑去,回来其实近似乘以2就行。(其实并不是乘以2)

设f[i][j][r]指的是从(A,B)走到(i,j)经过(i,j)有r次的最优解,那么显然是从四个方向走来的吧。

转移是f[i][j][r]=Max{f[x][y][r-1]}+c[i][j](x,y指的是(i,j)四个相邻点)

回去就是f[i][j][r]+Max{f[x][y][r-1]},那是Ci,j少记一次。

然后剩余的步数(只记去,此时K已经除以2)就是K-r,余数走的步数就是

(K-r)*(Max{c[x][y]}+c[i][j])

然后每次到(i,j)r次计算一下答案。

那个r一维可以滚存,r的取值范围是[0,Min(k,n*m)]

Code:

  1. # include<bits/stdc++.h>
  2. # define fp(i,s,t) for (int i=s;i<=t;i++)
  3. # define inf (0x7f7f7f7f7fll)
  4. # define int long long
  5. using namespace std;
  6. const int N=;
  7. int f[N][N][],c[N][N];
  8. int n,m,A,B,K,ans;
  9. int Get_Max(int a,int b,int c,int d)
  10. {
  11. if (b>a) a=b;
  12. if (c>a) a=c;
  13. if (d>a) a=d;
  14. return a;
  15. }
  16. template <typename T>inline void read(T& t)
  17. {
  18. char c=getchar();t=;
  19. while(c<''||c>'')c=getchar();
  20. while(c>=''&&c<='')t=(t<<)+(t<<)+(c^),c=getchar();
  21. }
  22. template <typename T,typename... Args> inline void read(T& t, Args&... args)
  23. {
  24. read(t);read(args...);
  25. }
  26. void write(int x)
  27. {
  28. if (x>) write(x/);
  29. putchar(''+x%);
  30. }
  31. void writeln(int x)
  32. {
  33. write(x);putchar('\n');
  34. }
  35. signed main()
  36. {
  37. read(n,m,A,B,K);
  38. if (K&) { puts("");exit();}
  39. K=K>>;
  40. fp(i,,n+) fp(j,,m+)
  41. c[i][j]=f[i][j][]=f[i][j][]=-inf;
  42. fp(i,,n) fp(j,,m) read(c[i][j]);
  43. f[A][B][]=; ans=-inf;
  44. fp (r,,min(K,n*m)) {
  45. int now=r&;
  46. int pst=now^;
  47. fp(i,,n) fp(j,,m) {
  48. int temp=Get_Max(f[i-][j][pst],f[i+][j][pst],f[i][j-][pst],f[i][j+][pst]);
  49. f[i][j][now]=max(temp+c[i][j],-inf);
  50. if (f[i][j][now]<) continue;
  51. int Whole_Dist=f[i][j][now]+temp;
  52. Whole_Dist+=(K-r)*(c[i][j]+Get_Max(c[i-][j],c[i+][j],c[i][j-],c[i][j+]));
  53. ans=max(ans,Whole_Dist);
  54. }
  55. }
  56. writeln(ans);
  57. return ;
  58. }

Problem5 Sunčanje

一道暴力的神仙T5,一看到数据范围就不想暴力的。

但是算算暴力的期望还是值得的。

先按照矩形右下角的x坐标排序,然后枚举每一个长方形,i,看看前面的长方形j是不是包含在i里面的,

被包含的必要条件是a[i].x-a[i].len<a[j].x对吧,不满足必要条件的那么前面也不满足必要条件,直接跳掉。

然后花四个图看看判包含。

  1.   (a[i].y>a[j].y&&a[i].y<a[j].y+a[j].wid)
  2. ||(a[i].y+a[i].wid>a[j].y&&a[i].y+a[i].wid<a[j].y+a[j].wid)
  3. ||(a[j].y>a[i].y&&a[j].y<a[i].y+a[i].wid)
  4. ||(a[j].y+a[j].wid>a[i].y&&a[j].y+a[j].wid<a[i].y+a[i].wid)

更新的时候注意看看谁在谁的下面(一定是初始标号小的放在下面!)

然后瞎加点优化就可以用pascal过4000ms时限了(而C++不行)

然后我就把第19个点的时限改成了6000ms,于是pascal和C++都过了

如果C++代码在XOJ上过不了的话那么加一行

# pragma G++ optimize(3)

Code C++

  1. # pragma G++ optimize(3)
    # include <bits/stdc++.h>
  2. # define fp(i,s,t) for (int i=s;i<=t;i++)
  3. using namespace std;
  4. const int N=1e5+;
  5. struct rec{
  6. int x,y,len,wid,id;
  7. }a[N];
  8. int n;
  9. bool ans[N];
  10. inline int read()
  11. {
  12. int X=,w=; char c=;
  13. while(c<''||c>'') {w|=c=='-';c=getchar();}
  14. while(c>=''&&c<='') X=(X<<)+(X<<)+(c^),c=getchar();
  15. return w?-X:X;
  16. }
  17. inline void qsort(int l,int r)
  18. {
  19. if (l==r) return;
  20. int t=rand()%(r-l)+l;
  21. swap(a[t],a[l]);
  22. rec v=a[l]; int i=l,j=r;
  23. while (i<j) {
  24. while (i<j&&a[j].x>v.x) j--;
  25. if (i<j) {a[i]=a[j];i++;} else break;
  26. while (i<j&&a[i].x<v.x) i++;
  27. if (i<j) {a[j]=a[i];j--;} else break;
  28. }
  29. a[i]=v;
  30. if (l<j) qsort(l,j-);
  31. if (i<r) qsort(i+,r);
  32. }
  33. signed main()
  34. {
  35. srand(time(NULL)*);
  36. n=read();
  37. fp(i,,n) {
  38. a[i].x=read();a[i].y=read();a[i].len=read();a[i].wid=read();
  39. a[i].x+=a[i].len;
  40. a[i].id=i;
  41. }
  42. qsort(,n);
  43. fp(i,,n) {
  44. int j=i-;
  45. while (j>=&&(a[i].x-a[i].len<a[j].x)) {
  46. if ((a[i].y>a[j].y&&a[i].y<a[j].y+a[j].wid)
  47. ||(a[i].y+a[i].wid>a[j].y&&a[i].y+a[i].wid<a[j].y+a[j].wid)
  48. ||(a[j].y>a[i].y&&a[j].y<a[i].y+a[i].wid)
  49. ||(a[j].y+a[j].wid>a[i].y&&a[j].y+a[j].wid<a[i].y+a[i].wid))
  50. {
  51. if (a[i].id<a[j].id) ans[a[i].id]=;
  52. else ans[a[j].id]=;
  53. }
  54. j--;
  55. }
  56. }
  57. fp(i,,n)
  58. if (ans[i]) putchar('N'),putchar('E'),putchar('\n');
  59. else putchar('D'),putchar('A'),putchar('\n');
  60. return ;
  61. }

Code Pascal

  1. VAR
  2. n,i,j:int64; x,y,len,wid,poza,raspuns:array[..] of int64;
  3. function Poz(a1,b1 : int64) : int64;
  4. VAR aux,piv:int64;
  5. Begin
  6. piv:=x[a1];
  7. while (a1 < b1) do
  8. Begin
  9. if (x[a1] > x[b1]) then Begin
  10. aux:=x[a1]; x[a1]:=x[b1]; x[b1]:=aux;
  11. aux:=y[a1]; y[a1]:=y[b1]; y[b1]:=aux;
  12. aux:=len[a1]; len[a1]:=len[b1]; len[b1]:=aux;
  13. aux:=wid[a1]; wid[a1]:=wid[b1]; wid[b1]:=aux;
  14. aux:=poza[a1]; poza[a1]:=poza[b1]; poza[b1]:=aux; end;
  15. if (piv = x[a1]) then b1:=b1 - else a1:=a1 + ;
  16. end;
  17. Poz:=a1;
  18. end;
  19. procedure Quick(a1,b1 : int64);
  20. VAR k:int64;
  21. Begin
  22. if (a1 < b1) then
  23. Begin
  24. k:=Poz(a1,b1);
  25. Quick(a1,k - );
  26. Quick(k + ,b1);
  27. end;
  28. end;
  29. Begin
  30. Readln(n);
  31. for i:= to n do
  32. Begin
  33. Readln(x[i],y[i],len[i],wid[i]);
  34. x[i]:=x[i] + len[i];
  35. poza[i]:=i;
  36. end;
  37. Quick(,n);
  38. raspuns[]:=;
  39. for i:= to n do
  40. Begin
  41. j:=i - ;
  42. while (j > ) and (x[i] - len[i] < x[j]) do
  43. Begin
  44. if (((y[i] > y[j]) and (y[i] < y[j] + wid[j]))
  45. or ((y[i] + wid[i] > y[j]) and (y[i] + wid[i] < y[j] + wid[j])))
  46. or (((y[j] > y[i]) and (y[j] < y[i] + wid[i]))
  47. or ((y[j] + wid[j] > y[i]) and (y[j] + wid[j] < y[i] + wid[i]))) then
  48. Begin
  49. if (poza[i] < poza[j]) then raspuns[poza[i]]:= else raspuns[poza[j]]:=;
  50. end;
  51. j:=j - ;
  52. end;
  53. end;
  54. for i:= to n do
  55. if (raspuns[i] = ) then Writeln('NE') else Writeln('DA');
  56. END.

COCI 2018/2019 CONTEST #2 Solution的更多相关文章

  1. COCI 2018/2019 CONTEST #2 T4 Maja T5Sunčanje Solution

    COCI 2018/2019 CONTEST #2 T4 T5 Solution abstract 花式暴力 #2 T5 Sunčanje 题意 按顺序给你1e5个长方形(左下角坐标&& ...

  2. 20172328 2018—2019《Java软件结构与数据结构》第二周学习总结

    20172328 2018-2019<Java软件结构与数据结构>第二周学习总结 概述 Generalization 本周学习了第三章集合概述--栈和第四章链式结构--栈.主要讨论了集合以 ...

  3. 2018 - 2019 CTU Open Contest E. Locker Room 【后缀数组】

    任意门:http://codeforces.com/gym/101954/problem/E E. Locker Room time limit per test 2.0 s memory limit ...

  4. 2018 - 2019 CTU Open Contest H. Split Game 【SG函数】

    H. Split Game time limit per test 1.0 s memory limit per test 256 MB input standard input output sta ...

  5. 2018 Multi-University Training Contest 1 Solution

    A - Maximum Multiple 题意:给出一个n 找x, y, z 使得$n = x + y +z$ 并且 $n \equiv 0 \pmod x, n \equiv 0 \pmod y, ...

  6. 2018 Multi-University Training Contest 2 Solution

    A - Absolute 留坑. B - Counting Permutations 留坑. C - Cover 留坑. D - Game puts("Yes") #include ...

  7. 2018 Multi-University Training Contest 3 Solution

    A - Problem A. Ascending Rating 题意:给出n个数,给出区间长度m.对于每个区间,初始值的max为0,cnt为0.遇到一个a[i] > ans, 更新ans并且cn ...

  8. 2018 Multi-University Training Contest 4 Solution

    A - Problem A. Integers Exhibition 留坑. B - Problem B. Harvest of Apples 题意:计算$\sum_{i = 0}^{i = m}C( ...

  9. 2018 Multi-University Training Contest 5 Solution

    A - Always Online Unsolved. B - Beautiful Now Solved. 题意: 给出一个n, k  每次可以将n这个数字上的某两位交换,最多交换k次,求交换后的最大 ...

随机推荐

  1. 解决eth0网卡无法自动加载的问题

    问题:输入ifup eth0显示无法加载网卡所在的文件 解决办法: vi /etc/rc.d/rc.local 最后一行加入: ifup eth0 然后重启虚拟机即可解决问题. 本文为博主原创文章,未 ...

  2. 20155202张旭《网络对抗技术》 week1 PC平台逆向破解及Bof基础实践

    20155202张旭<网络对抗技术> week1 PC平台逆向破解及Bof基础实践 1.实践目标: 实践对象:一个名为pwn1的linux可执行文件. 该程序正常执行流程是: main调用 ...

  3. 20155331《网络对抗》 Exp9 Web安全基础

    20155331<网络对抗> Exp9 Web安全基础 实验过程 WebGoat 在终端中输入java -jar webgoat-container-7.0.1-war-exec.jar开 ...

  4. HTTPUTILS

    maven依赖 <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId&g ...

  5. selenium+python自动化----xlrd,xlswriter

    1.准备: 使用之前需要先按照:打开cmd,输入pip install xlrd(xlswriter),点击enter; 2.基本使用: xlrd: #打开els文件,参数是文件路径: table = ...

  6. [T-ARA][Ma boo]

    歌词来源:http://music.163.com/#/song?id=22704447 作曲 : 金道勋/Rhymer [作曲 : 金道勋/Rhymer] 作词 : 金道勋 [作词 : 金道勋] 사 ...

  7. Hexo初体验

    title: Hexo初体验 date: 2018-05-10 tags: Hexo categories: Hexo --- Hexo本地安装 Node.js安装 Hexo npm安装如下 npm ...

  8. PAT甲题题解-1120. Friend Numbers (20)-水题

    博主欢迎转载,但请给出本文链接,我尊重你,你尊重我,谢谢~http://www.cnblogs.com/chenxiwenruo/p/6789775.html特别不喜欢那些随便转载别人的原创文章又不给 ...

  9. Python爬虫爬中文却显示Unicode,怎样显示中文--问题解答

    首先爬取古诗网站时,显示 原因是因为输出为列表[] 如果写一个循环,输出其中每个元素就为中文了...

  10. squid介绍和作用

    介绍 squid服务程序是一款在Unix系统中最为流行的高性能代理服务软件,通常会被当作网站的前置缓存服务,用于替代用户向网站服务器请求页面数据并进行缓存,通俗来讲,Squid服务程序会接收用户的请求 ...