bzoj4378 [POI2015]Logistyka

  对于询问(a,b),设X=(数列中小于等于b的数字和),Y=b*(数列中大于b的数字的个数),若X+Y>=a*b,则询问可行,否则不可行,实现的话用两个树状数组维护一下即可

  代码

  

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<set>
 4 #define fi first
 5 #define sc second
 6 #define mp make_pair
 7 #define N 2000100
 8 using namespace std;
 9 long long c1[N],c2[N],e[N],a[N],b[N];
10 int typ[N],n,i,m,tot,u,v[N];
11 char ch;
12 int ef(int x)
13 {
14     int l=1,r=n,m;
15     while (l<=r)
16     {
17         m=(l+r)>>1;
18         if (e[m]>x) r=m-1;else l=m+1;
19     }
20     return r;
21 }
22 int lowbit(int x)
23 {
24     return x&-x;
25 }
26 void cc(int x,int w,long long ww)
27 {
28     while (x<=n)
29     {
30         c1[x]+=w;
31         c2[x]+=ww;
32         x+=lowbit(x);
33     }
34 }
35 pair<int,long long> sum(int x)
36 {
37     int ans1=0;
38     long long ans2=0;
39     while (x)
40     {
41         ans1+=c1[x];
42         ans2+=c2[x];
43         x-=lowbit(x);
44     }
45     return mp(ans1,ans2);
46 }
47 int main()
48 {
49     scanf("%d%d",&n,&m);
50     tot++;e[tot]=0;
51     for (i=1;i<=m;i++)
52     {
53         scanf(" %c %lld%lld",&ch,&a[i],&b[i]);
54         if (ch=='U') 
55         {
56             tot++;e[tot]=b[i];
57             typ[i]=0;
58         }
59         else typ[i]=1;
60     }
61     sort(e+1,e+1+tot);e[0]=-1;n=0;
62     for (i=1;i<=tot;i++)
63     if (e[i]!=e[i-1]) e[++n]=e[i];
64     cc(1,n,n*e[1]);
65     for (i=1;i<=m;i++)
66     {
67         if (!typ[i])
68         {
69             u=ef(v[a[i]]);
70             cc(u,-1,-v[a[i]]);
71             v[a[i]]=b[i];
72             u=ef(v[a[i]]);
73             cc(u,1,v[a[i]]);
74         }
75         else
76         {
77             u=ef(b[i]);
78             pair<int,long long> ans2=sum(u);
79             long long v1=n-ans2.fi;
80             long long v2=ans2.sc;
81             if (v1*b[i]+v2>=a[i]*b[i])
82             printf("TAK
");
83             else
84             printf("NIE
");
85         }
86     }
87 }

  

原文地址:https://www.cnblogs.com/fzmh/p/5388887.html