2.

性质1:如果一个数字能被先手消去,那么就会立即被消去。

性质2:如果先手想消去当前的数字,那么一种可能的最优方案是先让后手消去k次,使得k*Y<a[i]<=k*Y+Y,然后自己花费相应的时间消去。

如果当前剩下的时间能消去一个数字,那么将需要花费的时间k加入大根堆中。

如果不能消去,但从以前调整某个消去的数字而将时间投入到当前数字上,并且这样能获得更多的时间,那么将堆顶弹出,将当前需要花费的时间k加入大根堆中。

否则,当前时间加一(显然是让后手把这个数字拿走)。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long int ll;
 4 const int maxn=5E5+5;
 5 const ll inf=1E15;
 6 int n,X,Y,a[maxn];
 7 int ans;
 8 bool used[maxn];
 9 inline int read()
10 {
11     char ch=getchar();
12     while(!isdigit(ch))ch=getchar();
13     int s=ch-'0';ch=getchar();
14     while(isdigit(ch)){s=s*10+ch-'0';ch=getchar();}
15     return s;
16 }
17 inline ll more(int pos)
18 {
19     return (a[pos]-1)/Y;
20 }
21 inline ll need(int pos)
22 {
23     ll g=more(pos);
24     return (a[pos]-g*Y-1)/X+1;
25 }
26 priority_queue<int>Q;
27 int main()
28 {
29 //    freopen("ex_monsters4.in","r",stdin);
30     ios::sync_with_stdio(false);
31     n=read(),X=read(),Y=read();
32     for(int i=1;i<=n;++i)
33         a[i]=read();
34     ll now=1;
35     for(int i=1;i<=n;++i)
36     {
37         ll x=more(i),y=need(i);
38         now+=x;
39 //        cout<<"? "<<i<<" "<<now<<" "<<x<<" "<<y<<" "<<ans<<endl;
40         if(y<=now)
41         {
42             now-=y;
43             ans+=1;
44             used[i]=1;
45             Q.push(y);
46         }
47         else if(Q.size()&&y<Q.top())
48         {
49             int z=Q.top();
50             Q.pop();
51             Q.push(y);
52             
53             now+=z;
54             ++now;
55             now-=y;
56         }
57         else
58             ++now;
59     }
60     cout<<ans<<endl;
61     return 0;
62 }
View Code

3.

问题:什么时候k种颜色的球,每种有a[i]种,排列数是偶数?

答案:当且仅当a[i]是2的次幂,并且按位或是S,其中S是所有a[i]的和。

证明:如果是2的次幂,可以证明1~S的lowbit之和等于所有1~a[i]的lowbit之和。如果不是,那么一个不是2的次幂的数就能被拆成若干个2的次幂的和,而这个数的lowbit显然小于2的次幂的lowbit之和。最后.......

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long int ll;
 4 bitset<2<<18>f,g;
 5 ll n,m,S;
 6 int a[555];
 7 inline void solve()
 8 {
 9     cin>>m>>S>>n;
10     for(int i=1;i<=n;++i)
11         cin>>a[i];
12     f.reset();
13     f[0]=1;
14     for(int i=0;i<63;++i)
15     {
16         if(m&(1ll<<i))
17         {
18             g.reset();
19             for(int j=1;j<=n;++j)
20                 g^=f<<a[j];
21             f=g;
22         }
23         if(S&(1ll<<i))
24         {
25             g.reset();
26             for(int j=0;j<(1<<17);++j)
27                 g[j]=f[j<<1|1];
28         }
29         else
30         {
31             g.reset();
32             for(int j=0;j<(1<<17);++j)
33                 g[j]=f[j<<1];
34         }
35         f=g;
36     }
37     cout<<f[0]<<endl;
38 }
39 int main()
40 {
41     ios::sync_with_stdio(false);
42     int T;
43     cin>>T;
44     while(T--)
45         solve();
46     return 0;
47 }
View Code

 

 posted on 2020-10-29 19:07  GreenDuck  阅读(111)  评论(0编辑  收藏  举报