Codeforces Round #576 (Div. 2) | CF1199 补题

A. City Day  用了st表//是不是麻烦了 

建表然后O(1)查询这个数前面x个数的最小值和后面y个数的最小值,注意边界和x,y为0的情况。

 1 #include<bits/stdc++.h>
 2 #include<iostream>
 3 #include<stack>
 4 #include<algorithm>
 5 #include<cstdio>
 6 #include<cmath>
 7 #include<cstring>
 8 #define mem(a) memset(a,0,sizeof(a))
 9 #define memm(a) memset(a,inf,sizeof(a))
10 #define ll long long
11 #define ld long double
12 #define uL unsigned long long
13 #define pb push_back
14 #define inf 0x3f3f3f3f
15 using namespace std;
16 const int N=1e5+5;
17 const int M=100+5;
18 int n,m,k,a[N],b[N],x,y;
19 int cnt,sum,mx,st[N][25];
20 void findm()
21 {
22     for(int i=0;i<n;i++) {st[i][0]=a[i];}
23     for(int j=1;j<25;j++)
24         for(int i=0;i<n;i++)
25            if(i+(1<<(j-1))<n)
26              st[i][j]=min(st[i][j-1],st[i+(1<<(j-1))][j-1]);
27 }
28 int query(int l,int r)
29 {
30     if(l>r) return inf;
31     int len=log2(r-l+1);
32     return min(st[l][len],st[r-(1<<len)+1][len]);
33 }
34 int main()
35 {
36     cin>>n>>x>>y;
37     for(int i=0;i<n;i++)
38         cin>>a[i];
39     findm();
40     for(int i=0;i<n;i++)
41     {
42         if(query(max(0,i-x),max(0,i-1))>a[i] || i==0)
43         {
44             if((a[i]<query(min(n-1,i+1),min(n-1,i+y)))||i==n-1)
45             {
46                 cout<<i+1<<endl;
47                 return 0;
48             }
49         }
50     }
51     return 0;
52 }
CF1199 A

我真傻,真的。就怕tle的,没想到暴力还真过了,狗屎,悲剧,痛不欲生,果然不能对A题小心呵护,要霸王直上么(′д` )…彡…彡  //最狗的是,时间还更快。

 1 #include<bits/stdc++.h>
 2 #include<iostream>
 3 #include<stack>
 4 #include<algorithm>
 5 #include<cstdio>
 6 #include<cmath>
 7 #include<cstring>
 8 #define fio ios::sync_with_stdio(false);cin.tie(0)
 9 #define mem(a) memset(a,0,sizeof(a))
10 #define memm(a) memset(a,inf,sizeof(a))
11 #define ll long long
12 #define ld long double
13 #define uL unsigned long long
14 #define pb push_back
15 #define inf 0x3f3f3f3f
16 using namespace std;
17 const int N=1e5+5;
18 const int M=1e9+5;
19 int n,m,k,x,a[N],y,vis[N];
20 int main()
21 {
22      cin>>n>>x>>y;
23      for(int i=1;i<=n;i++)
24         cin>>a[i];
25      for(int i=1;i<=n;i++)
26      {
27          int f=0;
28         for(int j=i-1;j>max(0,i-x-1);j--)
29          if(a[j]<a[i]) {f=1;break;}
30         for(int j=i+1;j<min(n+1,i+y+1);j++)
31          if(a[j]<a[i]) {f=1;break;}
32         if(f==0) {cout<<i<<endl;break;}
33      }
34      return 0;
35 }
CF1199 A -- 悲惨世界

B. Water Lily

在double上错了好几次,太傻了,而且最开始没看到等腰,更傻了(ノへ ̄、) 

CF1199 B

再一次,发现不是被double坑了,而是,被h和l的类型。。。 设成double或者ll就可以了,这个原理,,

1 int main()
2 {
3      ll h,l;
4      scanf("%I64d%I64d",&h,&l);
5      printf("%.13f\n", (l*l-h*h)/2.0/h );
6      return 0;
7 }
<(_ _)>

C. MP3  

//不知道是不是想的太麻烦了,时间要800多,晚点再看看 ---》好吧,加了fio就从800到200了orz

先判断是否满足,不满足就找临界的那个点,对数函数移项(记得要用种数减),然后枚举l,得到最小d的消费数(把a排序,l的前面+r的后面的数)。

tips:①用v保存每种数第一个数的下标,这之前a排个序。 ②仔细读题,向上取整(呜呼) 

 1 #include<bits/stdc++.h> 
 2 #define fio ios::sync_with_stdio(false);cin.tie(0) 
 3 #define ll long long 
 4 #define pb push_back
 5 #define inf 0x3f3f3f3f
 6 using namespace std;
 7 const int N=4e5+5; 
 8 int n,m,I,k,a[N],b[N],mx,x,y,ans;
 9 vector<int>v;
10 int f(int l,int r)
11 {
12      if(l>r) return inf;
13      if(r==v.size()-1) return v[l]-1;
14      return v[l]+n-v[r+1];
15 
16 }
17 int quickpow(int a,int n)
18 {
19     int ans=1;
20     while(n)
21     {
22         if(n&1) ans*=a;
23         n>>=1;
24         a*=a;
25     }
26     return ans;
27 }
28 int inter(int m)
29 {
30    return (log2(m)!=int(log2(m)))?log2(m)+1:log2(m);
31 }
32 int main()
33 {
34     fio;
35     cin>>n>>I;
36     I*=8;
37     for(int i=1;i<=n;i++)
38       cin>>a[i];
39     sort(a+1,a+n+1);
40     int now=-1,id=0;
41     for(int i=1;i<=n;i++)
42     {
43         if(a[i]!=now)
44         {
45            id=i;
46            now=a[i];
47            v.pb(id);
48         }
49     }
50     k=v.size();
51     ans=(inter(k)*n)-I;
52     if(ans<=0)
53     {
54         cout<<0<<endl;
55         return 0;
56     }
57     int need=inf;
58     ans=k-quickpow(2,I/n);
59     for(int i=0;i<=ans;i++)
60        need=min(f(i,k-ans+i-1),need);
61     cout<<need<<endl;
62     return 0;
63 }
CF1199 C

D. Welfare State

//同样的代码,就算加了fio,cin也比scanf慢400多呀

本来想着要不要线段树或者分块的,但是觉得太麻烦了,单纯的数组就可以了。所有统一改的用all记录,取最大,用b记录这次询问修改的值;用vis标记单独改的,值存第几次询问,这里取最后一次修改这个值的次序;再来个数组记录从最后一次询问往前的修改最大值。最后输出就没单独修改过的和all比,另一个和b[修改次序+1]比.

 1 #include<bits/stdc++.h>
 2 #include<iostream>
 3 #include<stack>
 4 #include<algorithm>
 5 #include<cstdio>
 6 #include<cmath>
 7 #include<cstring>
 8 #define fio ios::sync_with_stdio(false);cin.tie(0)
 9 #define mem(a) memset(a,0,sizeof(a))
10 #define memm(a) memset(a,inf,sizeof(a))
11 #define ll long long
12 #define ld long double
13 #define uL unsigned long long
14 #define pb push_back
15 #define inf 0x3f3f3f3f
16 using namespace std;
17 const int N=2e5+5;
18 const int M=1e9+5;
19 int n,m,k,x,a[N],q,y,b[N],vis[N];
20 int main()
21 {
22      fio;
23      cin>>n;
24      for(int i=1;i<=n;i++)
25         cin>>a[i];
26      cin>>k;
27      for(int i=1;i<=k;i++)
28      {
29          cin>>q>>x;
30          if(q==1)
31          {
32              cin>>y;
33              a[x]=y;
34              vis[x]=i;
35          }
36          else
37          {
38              m=max(m,x);
39              b[i]=x;
40          }
41      }
42      for(int i=k-1;i>=1;i--)
43         b[i]=max(b[i],b[i+1]);
44      for(int i=1;i<=n;i++)
45      {
46          if(!vis[i])
47             cout<<max(a[i],m)<<" ";
48          else
49             cout<<max(b[vis[i]],a[i])<<" ";
50      }
51      cout<<endl;
52      return 0;
53 }
CF1199 D

E. Matching vs Independent Set

//个人理解,有误望指正<(_ _)>

题意是找n个边或点,边要满足任意两条边没有公共点(匹配边),点要满足任意两点没有直达边(独立点),要注意点总共有3*n个。

根据数学知识,我们可以得到,边最多有(3*n)*(3*n-1)/2条(简单图,无平行边),而匹配边最多有3*n/2条(如n=2,一种情况是1-2,3-4,5-6),独立点最多有3*n-1个(样例3)

若某两条边有公共点,那除了公共点之外的两点相互独立,是独立点;如果没有公共点,就成两条匹配边;所以匹配边和独立点是此消彼长的。所以!不存在Impossible的情况,一定是Matching或IndSet或两者都有的情况.大概就是匹配边就算减到没影了,独立点本身个数加上随着增加的也够n个了。

 1 #include<bits/stdc++.h>
 2 #define fio ios::sync_with_stdio(false);cin.tie(0)
 3 #define mem(a) memset(a,0,sizeof(a))
 4 #define memm(a) memset(a,inf,sizeof(a))
 5 #define ll long long
 6 #define pb push_back
 7 #define inf 0x3f3f3f3f
 8 using namespace std;
 9 const int N=5e5+5;
10 const int M=1e9+5;
11 int n,m,k,a,b,vis[N];
12 int main()
13 {
14     fio;
15     int t;
16     cin>>t;
17     for(int k=1;k<=t;k++)
18     {
19         cin>>n>>m;
20         vector<int>num;
21         for(int i=1;i<=m;i++)
22         {
23             cin>>a>>b;
24             if(vis[a]!=k&&vis[b]!=k)
25             {
26                 num.pb(i);
27                 vis[a]=vis[b]=k; //用1的话,每次k变化都要重新清零
28             }
29         }
30         if(num.size()>=n)
31         {
32             cout << "Matching"<<endl;
33             for(int i=0;i<n;i++)
34                 cout<<num[i]<<" ";
35         }
36         else
37         {
38             cout << "IndSet"<<endl;
39             int now=0;
40             for(int i=1;i<=3*n;i++)
41             {
42                 if(vis[i]!=k) cout<<i<<" ",now++;
43                 if(now==n) break;
44             }
45         }
46         cout<<endl;
47     }
48 
49     return 0;
50 }
…(⊙_⊙;)…

 

转载于:https://www.cnblogs.com/XXrll/p/11275319.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值