codeforces round 420 div2 补题 CF 821 A-E

Okabe and Future Gadget Laboratory

暴力 

#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
const LL N=51,M=1,MOD=1;
int num[N][N];





int main()
{
 ios::sync_with_stdio(false);
 //freopen("t.txt","r",stdin);
 int n;
 scanf("%d",&n);
 for(int i=0;i<n;i++)
 	for(int j=0;j<n;j++)
 		scanf("%d",&num[i][j]);
 for(int i=0;i<n;i++)
 	for(int j=0;j<n;j++)
 		{
 		 if(num[i][j]==1)continue;
 		 bool flag=false;
 		 for(int ii=0;ii<n;ii++)
 		 	{
 		 	 int a=num[i][j]-num[ii][j];
 		 	 for(int jj=0;jj<n;jj++)
 		 	 	if(num[i][jj]==a){flag=true;break;}
 		 	 if(flag)break;
			}
		 if(!flag){printf("No
");return 0;}
		}
 printf("Yes
"); 
 return 0;
}

Okabe and Banana Trees

二分优化+等差数列求和

#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
const LL N=1,M=1,MOD=1;
 LL m,b;
LL count(LL x,LL y)
{
 return (y*(y+1)+x*(y+1))*(x+1)/2;
}
const double eps=1e-9;
LL findx(LL y)
{
 LL l=0,r=100000000000000LL;
 LL ret=-1;
 while(l<=r)
 	{
 	 LL mid=(l+r)/2;
 	 if((m*y)>(m*b-mid))r=(mid-1);
 	 	else ret=mid,l=(mid+1);
	}
 return ret;
}




int main()
{
 ios::sync_with_stdio(false);
 //freopen("t.txt","r",stdin);

 scanf("%I64d%I64d",&m,&b);
 LL ans=0;
 for(int i=b;i>=0;i--)
 	{
 	 ans=max(ans,count(findx(i),i));
 	 
	}
 printf("%I64d
",ans);
 return 0;
}

Okabe and Boxes

维护一个平衡树和一个栈 贪心即可

#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
const LL N=1,M=1,MOD=1;
map<int,int>m;
stack<int>s;
int n;




int main()
{
 ios::sync_with_stdio(false);
// freopen("t.txt","r",stdin);
 scanf("%d",&n);
 char c[20];
 int q,ans=0,sum=0;
 for(int i=0;i<n*2;i++)
 	{
 	 memset(c,0,sizeof(c));
 	 scanf("%s",&c);
 	 if(c[0]=='a')
 	 	{
 	 	 scanf("%d",&q);
 	 	 s.push(q);
		}
			else
				{sum++;
				 int maxv=0;
				 if(s.size()>0)maxv=s.top();
				 if(m.size()>0){map<int,int>::iterator it=m.begin();maxv=min(maxv,it->first);}
				 if((!s.empty())&&maxv==sum&&maxv==s.top())
				 	{
				 	 s.pop();continue;
				 	 
					 }
					 	else if(s.empty())
					 	{
					 	 map<int,int>::iterator it=m.begin();
					 	 m.erase(it->first);
						 }else
					 		{ans++;
					 		 while(!s.empty())
					 		 	{
					 		 	 m[s.top()]=1;
					 		 	 s.pop();
								}
							  map<int,int>::iterator it=m.begin();
							  
							  m.erase(it->first);
							 }
				}
	}
 printf("%d
",ans);
 return 0;
}

Okabe and City

这道题叙述的有问题 比赛中出现了偏差。。

略过吧,,感觉出题人也完全拎不清这道题。

/*#include <ext/pb_ds/assoc_container.hpp> 
#include <ext/pb_ds/tree_policy.hpp>*/
#include <bits/stdc++.h>

using namespace std;
//using namespace __gnu_pbds;
 
typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
//typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update> ordered_set;

#define FOR(i, a, b) for (int i=a; i<b; i++)
#define F0R(i, a) for (int i=0; i<a; i++)
#define FORd(i,a,b) for (int i = (b)-1; i >= a; i--)
#define F0Rd(i,a) for (int i = (a)-1; i >= 0; i--)
 
#define mp make_pair
#define pb push_back
#define f first
#define s second
#define lb lower_bound
#define ub upper_bound

const int MOD = 1000000007;
double PI = 4*atan(1);

int dr[10001], dc[10001];
vi row[10001], col[10001];
priority_queue<pii> todo;
vector<pii> lights;
int dist[10001];
map<pii,int> label;
int xdir[4] = {1,0,-1,0}, ydir[4] = {0,1,0,-1};
int n,m,k; 

void filrow(int i, int val){
    if (i >= 1 && i <= n && dr[i] == 0) {
        dr[i] = 1;
        for (int x: row[i]) if (val < dist[x]) {
            dist[x] = val;
            todo.push({-dist[x],x});
        }
    }
}

void filcol(int i, int val) {
    if (i >= 1 && i <= m && dc[i] == 0) {
        dc[i] = 1;
        for (int x: col[i]) if (val < dist[x]) {
            dist[x] = val;
            todo.push({-dist[x],x});
        }
    }
}

void ad(int x, int y, int val) {
    if (label.find({x,y}) != label.end()) 
        if (dist[label[{x,y}]] > val) {
            dist[label[{x,y}]] = val;
            todo.push({-val,label[{x,y}]});
        }
}

int main() {
    cin >> n >> m >> k;
    
    F0R(i,k) {
        int r,c; cin >> r >> c;
        lights.pb({r,c});
        row[r].pb(i);
        col[c].pb(i);
        label[{r,c}] = i;
    }
    
    F0R(i,10001) dist[i] = MOD;
    
    if (label.find({n,m}) == label.end()) {
        filrow(n-1,1);
        filrow(n,1);
        filcol(m-1,1);
        filcol(m,1);
    } else todo.push({0,label[{n,m}]});
    
    
    while (todo.size()) {
        auto a = todo.top(); todo.pop();
        a.f = -a.f;
        if (a.f > dist[a.s]) continue;
        
        F0R(i,4) ad(lights[a.s].f+xdir[i],lights[a.s].s+ydir[i],a.f);
        FOR(i,lights[a.s].f-2,lights[a.s].f+3) filrow(i,a.f+1);
        FOR(i,lights[a.s].s-2,lights[a.s].s+3) filcol(i,a.f+1);
    }
    
    if (dist[0] != MOD) cout << dist[0];
    else cout << -1;
}

  

Okabe and El Psy Kongroo

 题意非常简单 数据很特别, n只有100 高度只有16 但是长度很长。

看起来很像矩阵加速DP

考虑每个线段的特点,它可能很长,我们可以对于每个segment给出一个16*16的矩阵 元素(i,j)==1当且仅当可以从高度i转移到高度j

然后对每个区间进行矩阵快速幂,并且将他们相乘 最后一个矩阵的(k,0) 0<=k<=15 求和即是答案。

#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
const LL N=200,M=20,MOD=1000000007;
const LL mt_MAXN=60;const LL mt_MAXM=60;
struct Matrix
       {
        LL n,m;
		LL MOD;
		LL a[mt_MAXN][mt_MAXM];
		void clear()
				{
				 n=m=0;
				 memset(a,0,sizeof(a));
				}
		Matrix operator +(const Matrix &b)const
            {
			Matrix tmp;
			tmp.n=n;tmp.m=m;tmp.MOD=MOD;
            for(LL i=0;i<n;++i)
				for(LL j=0;j<m;++j)
					tmp.a[i][j]=(a[i][j]+b.a[i][j])%MOD;
 			 return tmp;
         	}
        Matrix operator -(const Matrix &b)const
            {
			Matrix tmp;
			tmp.n=n;tmp.m=m;tmp.MOD=MOD;
            for(LL i=0;i<n;++i)
				for(int j=0;j<m;++j)
					tmp.a[i][j]=(a[i][j]-b.a[i][j]+MOD)%MOD;
 			 return tmp;
         	}
		Matrix operator *(const Matrix &b)const
			{
			 Matrix tmp;
			 tmp.clear();
			 tmp.n=n;tmp.m=b.m;tmp.MOD=MOD;
 			 for(LL i=0;i<n;++i)
				for(LL j=0;j<b.m;++j)
					for(LL k=0;k<m;++k)
						tmp.a[i][j]=(tmp.a[i][j]+((a[i][k])*(b.a[k][j]))%MOD+MOD)%MOD;
			 return tmp;
			}
				
		Matrix iden()
				{
				 Matrix x;
				 memset(x.a,0,sizeof(x.a));
				 x.m=n;x.n=n;
				 x.MOD=MOD;
				 for(LL i=0;i<n;++i)
				     x.a[i][i]=1;
				 return x;
				}
		Matrix pow(LL t) 
				{
				 Matrix now;
				 now.n=n;now.m=m;now.MOD=MOD;
				 memset(now.a,0,sizeof(now.a));
				 for(LL i=0;i<n;++i)
					for(LL j=0;j<m;++j)
						now.a[i][j]=a[i][j];
				 for(LL i=1;i<t;i++)
					now=now*now;
				 return now;
				}
		Matrix qpow(LL t)
				{
				 if(n==0)return iden();
				 Matrix now;
				 now.clear();
				 now.n=n;now.m=m;now.MOD=MOD;
				 now=pow(1);
				 Matrix ans;
				 	 ans.clear();
				 ans.n=n;ans.m=m;ans.MOD=MOD;
			     ans=ans.iden();
				 while(true)
					{
					 if(t%2==1)ans=ans*now;
					 t=t/2;
					 now=now*now;
					 if(t==0)break;
					}
				 return ans;
				}
	   };

LL ab(LL x)
{
 if(x>0)return x;
 	else return -x;
}
int main()
{//freopen("t.txt","r",stdin);
 LL n,k;
 scanf("%I64d%I64d",&n,&k);
 Matrix id;
 id.n=id.m=16;id.MOD=MOD;
 id=id.iden();
 for(int i=0;i<n;i++)
 	{
 	 LL a,b,h;
 	 scanf("%I64d%I64d%I64d",&a,&b,&h);
 	 b=min(b,k);
 	 Matrix mn;
 	 mn.clear();
 	 mn.n=mn.m=16;mn.MOD=MOD;
 	 for(int ii=0;ii<=15;ii++)
 	 	for(int jj=0;jj<=15;jj++)
 	 		{
 	 		 if(ii>h||ii<0||jj>h||jj<0||ab(ii-jj)>1)continue;
 	 		 mn.a[ii][jj]=1;
			}
	 mn=mn.qpow(b-a);
	 id=id*mn;
	}
 printf("%I64d
",id.a[0][0]);
 return 0;
}

  

吐槽 ! 刚开始10分钟怎么也打不开网站 开VPN都不行 然后就延时。。

最后竟然还unrated.. 老哥能走点心不? 要不您做收费网站也行啊。

原文地址:https://www.cnblogs.com/heisenberg-/p/7078664.html