Codeforces Round #452 (Div. 2)

A:水题

#include<bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define pi acos(-1.0)
#define ll long long
#define mod 1000000007
#define C 0.5772156649
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#define pil pair<int,ll>
#define pii pair<int,int>
#define ull unsigned long long
#define base 1000000000000000000
#define fio ios::sync_with_stdio(false);cin.tie(0)

using namespace std;

const double g=10.0,eps=1e-12;
const int N=200000+10,maxn=90000+10,inf=0x3f3f3f3f;

int main()
{
    int n;
    scanf("%d",&n);
    int one=0,two=0;
    for(int i=0;i<n;i++)
    {
        int x;
        scanf("%d",&x);
        if(x==1)one++;
        else two++;
    }
    int ans=0;
    ans+=min(two,one);
    one-=min(two,one);
    printf("%d\n",ans+one/3);
    return 0;
}
/********************

********************/
A

B:也很水,不过我看很多人被kack了,可能处理有点麻烦,我是直接转化成字符串然后匹配

#include<bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define pi acos(-1.0)
#define ll long long
#define mod 1000000007
#define C 0.5772156649
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#define pil pair<int,ll>
#define pii pair<int,int>
#define ull unsigned long long
#define base 1000000000000000000
#define fio ios::sync_with_stdio(false);cin.tie(0)

using namespace std;

const double g=10.0,eps=1e-12;
const int N=200000+10,maxn=90000+10,inf=0x3f3f3f3f;

string s="312831303130313130313031312831303130313130313031312831303130313130313031312931303130313130313031312831303130313130313031312831303130313130313031312831303130313130313031";
int main()
{
    fio;
    int n;
    cin>>n;
    string p="";
    for(int i=0;i<n;i++)
    {
        string te;
        cin>>te;
        p+=te;
    }
    for(int i=0;i<s.size();i++)
    {
        if(s.substr(i,p.size())==p)
        {
            cout<<"YES\n";
            return 0;
        }
    }
    cout<<"NO\n";
    return 0;
}
/********************

********************/
B

C:有一个n,1到n,分两组,要求和的差最小,直接从大到小贪心

#include<bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define pi acos(-1.0)
#define ll long long
#define mod 1000000007
#define C 0.5772156649
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#define pil pair<int,ll>
#define pii pair<int,int>
#define ull unsigned long long
#define base 1000000000000000000
#define fio ios::sync_with_stdio(false);cin.tie(0)

using namespace std;

const double g=10.0,eps=1e-12;
const int N=200000+10,maxn=90000+10,inf=0x3f3f3f3f;

int main()
{
    int n;
    scanf("%d",&n);
    ll sum=(ll)(1+n)*n/2;
    if(sum%2==0)puts("0");
    else puts("1");
    sum/=2;
    vector<int>v;
    for(int i=n;i>=1;i--)
    {
        if(sum-i>=0)
        {
            sum-=i;
            v.pb(i);
        }
    }
    printf("%d ",v.size());
    for(int i=0;i<v.size();i++)
        printf("%d ",v[i]);
    puts("");
    return 0;
}
/********************

********************/
C

D:题意:给一个n,求从1到n中选两个数,加起来末尾的9最多的情况数

题解:先找在5,50,500.。。。那个区间里,然后枚举,末尾9的个数相同的数,然后直接套公式即可

#include<bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define pi acos(-1.0)
#define ll long long
#define mod 1000000007
#define C 0.5772156649
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#define pii pair<int,int>
#define ull unsigned long long
#define base 1000000000000000000
#define fio ios::sync_with_stdio(false);cin.tie(0)

using namespace std;

const double g=10.0,eps=1e-12;
const int N=40000+10,maxn=200000+10,inf=0x3f3f3f3f;

ll p[20];
int main()
{
    ll n;
    scanf("%lld",&n);
    if(n<5)
    {
        printf("%lld\n",(n*n-n)/2);
        return 0;
    }
    p[0]=5;
    for(ll i=1;i<=10;i++)p[i]=p[i-1]*10;
    int id=upper_bound(p,p+10,n)-p;
    --id;
    ll ans=0;
    for(ll i=p[id]*2-1;i<p[id+1]*2-1;i+=p[id]*2)
    {
        if(2*n<=i)break;
      //  cout<<i<<endl;
        ans+=min(i-1,n)-(i+1)/2+1;
        //cout<<ans<<endl;
    }
    printf("%lld\n",ans);
    return 0;
}
/********************

********************/
D

E:题意:n个数,每次删除最左边的连续相同数字最多的那个区间,问要删几次;

题解:优先队列维护,先按连续数字相同排序,其次按坐标排序,然后对于每次操作,看删除这个区间之后前后会不会连起来,会的话就把这个合并区间加入队列原来的两个删掉,否则不管

#include<bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define pi acos(-1.0)
#define ll long long
#define mod 1000000007
#define C 0.5772156649
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#define pii pair<int,int>
#define ull unsigned long long
#define base 1000000000000000000
#define fio ios::sync_with_stdio(false);cin.tie(0)

using namespace std;

const double g=10.0,eps=1e-12;
const int N=200000+10,maxn=200000+10,inf=0x3f3f3f3f;

struct seg{
    int l,r,v,num;
    bool operator <(const seg &rhm)const{
        if(num==rhm.num)return l>rhm.l;
        return num<rhm.num;
    }
}s[N*10];
priority_queue<seg>q;
map<int,int>ma[N];
int lrtoid[N];
int pre[N],last[N];
int Hash[N];
int main()
{
    int n,sz=0,id=0,cnt=0;
    scanf("%d",&n);
    scanf("%d",&s[++id].v);
    Hash[cnt++]=s[id].v;
    pre[s[id].l]=-1;
    s[id].l=s[id].r=s[id].num=1;
    for(int i=2;i<=n;i++)
    {
        int x;
        scanf("%d",&x);
        if(x==s[id].v)
        {
            s[id].r++,s[id].num++;
        }
        else
        {
            lrtoid[s[id].l]=lrtoid[s[id].r]=id;
            pre[s[id].r+1]=s[id].r;
            last[s[id].r]=s[id].r+1;
            Hash[cnt++]=s[id].v;
            q.push(s[id]);
            ++id;
            s[id].v=x,s[id].l=s[id].r=i,s[id].num=1;
        }
    }
    lrtoid[s[id].l]=lrtoid[s[id].r]=id;
    last[s[id].r]=-1;
    Hash[cnt++]=s[id].v;
    q.push(s[id]);
    sort(Hash,Hash+cnt);
    cnt=unique(Hash,Hash+cnt)-Hash;
    for(int i=1;i<=id;i++)s[i].v=lower_bound(Hash,Hash+cnt,s[i].v)-Hash;
//    while(!q.empty())
//    {
//        seg s=q.top();
//        q.pop();
//        printf("%d %d %d %d\n",s.l,s.r,s.v,s.num);
//    }
    int ans=0;
    while(!q.empty())
    {
        seg ss=q.top();
        q.pop();
      //  printf("%d %d %d %d\n",ss.l,ss.r,ss.v,ss.num);
        if(ma[ss.l][ss.r])continue;
        ans++;
        if(pre[ss.l]==-1&&last[ss.r]==-1)break;
        else if(pre[ss.l]==-1&&last[ss.r]!=-1)pre[last[ss.r]]=-1;
        else if(pre[ss.l]!=-1&&last[ss.r]==-1)last[pre[ss.l]]=-1;
        else
        {
            int id1=lrtoid[pre[ss.l]],id2=lrtoid[last[ss.r]];
            if(s[id1].v==s[id2].v)
            {
                ma[s[id1].l][s[id1].r]=ma[s[id2].l][s[id2].r]=1;
                s[++id].l=s[id1].l,s[id].r=s[id2].r,s[id].num=s[id1].num+s[id2].num,s[id].v=s[id1].v;
                lrtoid[s[id].l]=lrtoid[s[id].r]=id;
                q.push(s[id]);
            }
            else
            {
                last[s[id1].r]=s[id2].l;
                pre[s[id2].l]=s[id1].r;
            }
        }
    }
    printf("%d\n",ans);
    return 0;
}
/********************

********************/
E

F:题意:一个字符串,m次操作,每次操作删除区间l到r之间的所有字符c,求完成操作后的字符串

题解:对于每一种字符维护一个set,插入坐标,每次删除就删掉该区间对应坐标,剩下的问题就是如何将给定的区间映射到原区间,我们采用树状数组维护,每次删除该点时,就在树状数组里-1,映射时用二分,复杂度O(nloglogn)

#include<bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define pi acos(-1.0)
#define ll long long
#define mod 1000000007
#define C 0.5772156649
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#define pii pair<int,int>
#define ull unsigned long long
#define base 1000000000000000000
#define fio ios::sync_with_stdio(false);cin.tie(0)

using namespace std;

const double g=10.0,eps=1e-12;
const int N=200000+10,maxn=200000+10,inf=0x3f3f3f3f;

int sum[N],n,m;
void add(int x,int v)
{
    while(x<N)
    {
        sum[x]+=v;
        x+=x&(-x);
    }
}
int query(int x)
{
    int ans=0;
    while(x>0)
    {
        ans+=sum[x];
        x-=x&(-x);
    }
    return ans;
}
int change(int x)
{
    int l=0,r=n+1;
    while(l<r-1)
    {
        int m=(l+r)>>1;
        if(query(m)>=x)r=m;
        else l=m;
    }
    return r;
}
set<int>s[123];
bool vis[N];
int main()
{
    fio;
    string p;
    cin>>n>>m>>p;
    for(int i=0;i<n;i++)
    {
        add(i+1,1);
        s[p[i]].insert(i+1);
    }
    while(m--)
    {
        int l,r;
        string te;
        cin>>l>>r>>te;
        l=change(l),r=change(r);
        //cout<<l<<" "<<r<<endl;
        int id=te[0];
        auto x=s[id].lower_bound(l);
        for(;x!=s[id].end();)
        {
            if((*x)>r)break;
            //cout<<(*x)<<"+++++";
            add((*x),-1);
            s[id].erase(x++);
        }
//        cout<<endl;
//        for(int i=1;i<=n;i++)cout<<query(i)<<" ";
//        cout<<endl;
    }
    for(int i=0;i<123;i++)
        for(auto x:s[i])
            vis[x-1]=1;
    for(int i=0;i<n;i++)
        if(vis[i])
            cout<<p[i];
    cout<<"\n";
    return 0;
}
/********************
10 4
agtFrgF4aF
2 5 g
4 9 F
1 5 4
1 7 a
********************/
F

 

posted @ 2017-12-21 23:25  walfy  阅读(207)  评论(0编辑  收藏  举报