Luogu P2114[NOI2014]起床困难综合症 【贪心/位运算】By cellur925

题目传送门

所以NOI的题现在简单惹?

30分做法:枚举开始的权值,n²过掉。

100分做法:竟然是贪心qwq。因为我们的计算背景是二进制下,所以我们贪心地想让每一位都是1.我们现在需要解决的问题,就是找到一个开始的攻击值。所以我们可以按位检查一下当前位是否可以为1,能不能更新答案。

Code

 1 #include<cstdio>
 2 #include<algorithm>
 3 
 4 using namespace std;
 5 typedef long long ll;
 6 
 7 ll lmax(ll a,ll b)
 8 {
 9     if(b>a) return b;
10     else return a;
11 }
12 
13 int n,m;
14 ll ans;
15 char opt[10];
16 struct door{
17     int op;
18     ll t;
19 }d[200000];
20 
21 ll work(ll x)
22 {
23     for(int i=1;i<=n;i++)
24     {
25         if(d[i].op==1)
26             x=x&d[i].t;
27         if(d[i].op==2)
28             x=x|d[i].t;
29         if(d[i].op==3)
30             x=x^d[i].t;
31     }
32     return x;
33 } 
34 
35 int main()
36 {
37     scanf("%d%d",&n,&m);
38     for(int i=1;i<=n;i++)
39     {
40         scanf("%s",opt+1);
41         scanf("%lld",&d[i].t);
42         if(opt[1]=='A') d[i].op=1;
43         else if(opt[1]=='O') d[i].op=2;
44         else if(opt[1]=='X') d[i].op=3;         
45     }
46     /*for(int i=0;i<=m;i++)
47         ans=lmax(ans,work(i));*/
48     for(int i=31;i>=0;i--)
49     {
50         if(ans+(1<<i)>m) continue;
51         if(work(ans)<work(ans+(1<<i)))
52             ans+=(1<<i);
53     }
54     printf("%lld",work(ans));
55     return 0;
56 } 
View Code

 

posted @ 2018-09-23 15:04  cellur925&Chemist  阅读(122)  评论(0编辑  收藏  举报