[关闭]
@y20070316 2017-04-05T07:43:07.000000Z 字数 3085 阅读 826

【xsy2155】music

题目 分析 线段树


题意


分析

  可能的 只有 个,因为只有 个变化点 的值就是 个可能的值。
  我们将变化点从大到小排序,枚举变化点,单调地删除被忽略的点,并尝试求答案。

  由于我们知道 的值,终点的信息比较多,所以我们考虑倒推。
  求出第一次碰到 的位置 ,和碰到 的位置

  当 时,我们可以画出这样一幅图。

  若没有经过小于0的部分,则这段有解。
  且所有线下的路径都合法,所以一定有解,此时答案取
  若 ,那么合法区间为 ,我们取操作之和。

  同理当 时,我们可以画出这样一幅图。

  若没有经过大于 的部分,则这段有解。
  且所有线上的路径都合法,所以一定有解,此时答案取 。若 ,则合法区间为 ,所以我们取

实现

  1. #include <cstdio>
  2. #include <cctype>
  3. #include <algorithm>
  4. using namespace std;
  5. #define F(i,a,b) for (register int i=(a);i<=(b);i++)
  6. #define D(i,a,b) for (register int i=(a);i>=(b);i--)
  7. #define ls (x<<1)
  8. #define rs (x<<1|1)
  9. int n,Max,V2;
  10. int but[100005];
  11. struct OP { int t,id; friend inline int operator < (OP a,OP b) { return a.t>b.t; } }op[100005];
  12. struct Info {
  13. int sum,mn,mx;
  14. inline Info(int _sum=0,int _mn=(int)1e9,int _mx=(int)-1e9):sum(_sum),mn(_mn),mx(_mx){}
  15. friend inline Info operator + (Info a,Info b) {
  16. Info c; c.sum=a.sum+b.sum;
  17. c.mn=min(a.mn,a.sum+b.mn);
  18. c.mx=max(a.mx,a.sum+b.mx);
  19. return c;
  20. }
  21. };
  22. struct Seg {
  23. int l,r; Info val;
  24. }tr[300000];
  25. namespace input {
  26. const int S=2000000; char s[S]; char *h=s+S; char *t=h;
  27. inline char getchr(void) { if (h==t) { fread(s,1,S,stdin); h=s; } return *h++; }
  28. inline int rd(void) {
  29. int x=0,f=1; char c=getchr();
  30. for (;!isdigit(c);c=getchr()) if (c=='-') f=-1;
  31. for (;isdigit(c);c=getchr()) x=x*10+c-'0';
  32. return x*f;
  33. }
  34. inline int rdc(void) { char c=getchr(); while (c!='+'&&c!='-') c=getchr(); return c=='+'?-1:1; }
  35. }
  36. using input::rd;
  37. using input::rdc;
  38. void Build(int x,int l,int r) {
  39. tr[x].l=l,tr[x].r=r;
  40. if (l==r) tr[x].val=Info(but[l],but[l],but[l]);
  41. else {
  42. int mid=(l+r)>>1;
  43. Build(ls,l,mid);
  44. Build(rs,mid+1,r);
  45. tr[x].val=tr[ls].val+tr[rs].val;
  46. }
  47. }
  48. void Modify(int x,int loc,int w) {
  49. if (tr[x].l==tr[x].r) { tr[x].val=Info(w,w,w); return; }
  50. int mid=(tr[x].l+tr[x].r)>>1;
  51. loc<=mid?Modify(ls,loc,w):Modify(rs,loc,w);
  52. tr[x].val=tr[ls].val+tr[rs].val;
  53. }
  54. Info Prefix(int x,int loc) {
  55. if (tr[x].r<=loc) return tr[x].val;
  56. int mid=(tr[x].l+tr[x].r)>>1;
  57. if (loc<=mid) return Prefix(ls,loc);
  58. else return tr[ls].val+Prefix(rs,loc);
  59. }
  60. int FMin(int x,int sum) {
  61. if (tr[x].l==tr[x].r) return (tr[x].l-1)+(sum+tr[x].val.sum>0);
  62. int mid=(tr[x].l+tr[x].r)>>1;
  63. if (sum+tr[ls].val.mn<=0) return FMin(ls,sum);
  64. else return FMin(rs,sum+tr[ls].val.sum);
  65. }
  66. int FMax(int x,int sum) {
  67. if (tr[x].l==tr[x].r) return (tr[x].l-1)+(sum+tr[x].val.sum<Max);
  68. int mid=(tr[x].l+tr[x].r)>>1;
  69. if (sum+tr[ls].val.mx>=Max) return FMax(ls,sum);
  70. else return FMax(rs,sum+tr[ls].val.sum);
  71. }
  72. inline int Sum(int x) { return tr[x].val.sum; }
  73. void Init(void) {
  74. n=rd(),Max=rd(),V2=rd();
  75. but[0]=V2;
  76. D(i,n,1) {
  77. but[i]=rdc();
  78. op[i].t=rd(),op[i].id=i;
  79. }
  80. Build(1,0,n);
  81. }
  82. int calc(void) {
  83. int tMin=FMin(1,0)+1;
  84. int tMax=FMax(1,0)+1;
  85. if (tMin==n+1&&tMax==n+1) return Sum(1);
  86. else if (tMin<tMax) {
  87. Info data=Prefix(1,tMax);
  88. if (data.mn<0) return -1;
  89. if (tMax==n+1) return Sum(1);
  90. return Max;
  91. }
  92. else if (tMin>tMax) {
  93. Info data=Prefix(1,tMin);
  94. if (data.mx>Max) return -1;
  95. return Max;
  96. }
  97. }
  98. void Solve(void) {
  99. if (calc()!=-1) { printf("infinity\n"); return; }
  100. F(i,1,n) op[i].t-=op[i+1].t;
  101. sort(op+1,op+n+1);
  102. for (int l=1,r=1;l<=n;l=r+1,r=l) {
  103. while (r+1<=n&&op[l].t==op[r+1].t) r++;
  104. F(i,l,r) {
  105. but[op[i].id]=0;
  106. Modify(1,op[i].id,0);
  107. }
  108. int ans=calc(); if (ans!=-1) { printf("%d %d\n",op[l].t-1,ans); return; }
  109. }
  110. }
  111. int main(void) {
  112. #ifndef ONLINE_JUDGE
  113. freopen("sdchr.in","r",stdin);
  114. // freopen("sdchr.out","w",stdout);
  115. #endif
  116. Init();
  117. Solve();
  118. return 0;
  119. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注