Hello 2020(A-D)

https://codeforces.com/contest/1284/problem/A


思路:取循环节即可。

然而我第一眼直接map判定是否出现过相同的字符串,看了半天发现题目说字符串会重复。签到给我wa了3发。

#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
using namespace std;
const int maxn=1e7;
typedef long long LL;
inline LL read(){LL x=0,f=1;char ch=getchar();	while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
return x*f;}
string s[40],t1[40];
string ans[maxn];
map<string,LL>map1;
LL num=0;
int main(void){
   cin.tie(0);std::ios::sync_with_stdio(false);
   LL n,m;cin>>n>>m;
   for(LL i=1;i<=n;i++) cin>>s[i];
   for(LL j=1;j<=m;j++) cin>>t1[j];
   LL tot=1;LL cnt=1;
   LL q;cin>>q;
   while(q--){
      LL t;cin>>t;
      LL mod1=t%n;
      if(mod1==0) mod1=n;
      LL mod2=t%m;
      if(mod2==0) mod2=m;
      cout<<s[mod1]+t1[mod2]<<"\n";

   }
   return 0;
}

https://codeforces.com/contest/1284/problem/B


思路:开始想着就是一个小于等于x的值的和,树状数组套上去然鹅样例没过..后来改成前缀和但是wa9.

原因是数据范围存在0,如果把可以任意匹配的最小也存在0,会导致无法相加。

细节阿细节阿。所以全部+1

#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
using namespace std;
const int maxn=1e6+1000;
typedef long long LL;
inline LL read(){LL x=0,f=1;char ch=getchar();	while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
return x*f;}
LL l1[maxn],r1[maxn];
LL pre[maxn];
int main(void){
   cin.tie(0);std::ios::sync_with_stdio(false);
   LL n;cin>>n;
   for(LL i=1;i<=n;i++){
       LL maxv=-1;LL minv=1e15;
       LL l;cin>>l;
       bool flag=0;
       for(LL j=1;j<=l;j++){
          LL x;cin>>x;
          x++;
          if(minv<x) flag=1;
          if(maxv<x) maxv=x;
          if(minv>x) minv=x;
       }
       if(flag) minv=0,maxv=1e6+10;
       l1[i]=minv;r1[i]=maxv;
       pre[minv]++;
   }
   for(LL i=1;i<=1e6+10;i++){
       pre[i]+=pre[i-1];
   }
   LL ans=0;
   for(LL i=1;i<=n;i++){
       ans+=pre[r1[i]-1];
   }
   cout<<ans<<"\n";
   return 0;
}

https://codeforces.com/contest/1284/problem/C

思路:

贡献+组合数学。好久没碰到贡献的思路了。都想不起来了。

定义 区间[l,r]的长度len=r−l+1 ,那么 长度为len的里面可取的连续数字的范围一共有n-len+1 种。

然后其内部可以没有顺序fac[len],整体看成一个元素,和剩下的又可以无序,fac[n-len+1]。

所以长度为i的区间的贡献是 (n-len+1)*fac[len]*fac[n-len+1]

复杂度On

#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
using namespace std;
const int maxn=3e5+1000;
typedef long long LL;
inline LL read(){LL x=0,f=1;char ch=getchar();	while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
return x*f;}
LL fac[maxn];
int main(void){
   cin.tie(0);std::ios::sync_with_stdio(false);
   LL n,mod;cin>>n>>mod;
   fac[0]=1;
   for(LL i=1;i<maxn;i++) fac[i]=fac[i-1]*i%mod;
   LL ans=0;
   for(LL i=1;i<=n;i++){///枚举长度为i的区间贡献
       ans=(ans%mod+ ( (n-i+1)%mod*fac[i]%mod*fac[n-i+1]%mod)%mod)%mod;
   }
   cout<<ans<<"\n";
   return 0;
}

https://codeforces.com/contest/1284/problem/D

题意:n个表演,每个表演在a场地需要从[asi,aei]这段时间,在b场地需要从[bsi,bei]这段时间,
问是否能有两个表演在a冲突,在b不冲突。或者在a不冲突,在b冲突。

 

一开始实在不懂题意,懂了之后感觉这个题出的不错。

思路:

当你这么去模拟之后发现,对于处于b场地的一堆线段

比如这个3,需要满足<=2的这个st才可以满足条件,这样就可以优化之前的判断了,满足的话直接说明2和3也是可以的。原本要判<=1,2和3还要判<=2。突破口在于直接取一个最大的开头求解就行

参考:https://blog.csdn.net/qq_41730604/article/details/103970451?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-3.control&dist_request_id=1331974.8859.16185641507985183&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-3.control

 

#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
#define Fi first
#define Se second
using namespace std;
const int maxn=1e5+1000;
typedef long long LL;
inline LL read(){LL x=0,f=1;char ch=getchar();	while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
return x*f;}
pair< pair<LL,LL>, pair<LL,LL> >a[maxn];
bool cmp(pair< pair<LL,LL>, pair<LL,LL> > A,pair< pair<LL,LL>, pair<LL,LL> > B){
     return A.Fi.Fi<B.Fi.Fi;
}
struct Node{
    LL st,ed,id;
};
bool operator <(const Node& A,const Node& B){
         return A.ed>B.ed;
}
LL cnt=0;
LL solve(LL n){
    multiset<LL>mi,mx;
    priority_queue<Node>que;
    sort(a+1,a+1+n,cmp);
    for(LL i=1;i<=n;i++){
        while(!que.empty()&&que.top().ed<a[i].Fi.Fi){
              LL id=que.top().id;
              que.pop();
              mi.erase(a[id].Se.Se);
              mx.erase(a[id].Se.Fi);
        }
        if(!mi.empty()&&(*mi.begin())<a[i].Se.Fi) return 0;
        if(!mx.empty()&&(*mx.rbegin())>a[i].Se.Se) return 0;
        mi.insert(a[i].Se.Se);
        mx.insert(a[i].Se.Fi);
        que.push({a[i].Fi.Fi,a[i].Fi.Se,i});
    }
    return 1;
}
int main(void){
   cin.tie(0);std::ios::sync_with_stdio(false);
   LL n;cin>>n;
   for(LL i=1;i<=n;i++){
       cin>>a[i].Fi.Fi>>a[i].Fi.Se;
       cin>>a[i].Se.Fi>>a[i].Se.Se;
   }
   LL flag=1;
   flag=min(solve(n),flag);
   for(LL i=1;i<=n;i++){
      LL xx=a[i].Fi.Fi;
      LL yy=a[i].Fi.Se;
      a[i].Fi.Fi=a[i].Se.Fi;a[i].Fi.Se=a[i].Se.Se;
      a[i].Se.Fi=xx;a[i].Se.Se=yy;
   }
   flag=min(solve(n),flag);
   if(flag){
      cout<<"YES"<<"\n";
   }
   else{
       cout<<"NO"<<"\n";
   }
   return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值