codeforces#337 div2

这场比赛真是。。。涨分场又打成了掉分场。。。

唯一的收获就是理解了扫描线,以前放弃的,现在还是得学,要是之前学了,这场D就能过了。

A题:

#include<bits/stdc++.h>
#define REP(i,a,b) for(int i=a;i<=b;i++)
#define rep(i,a,b) for(int i=a;i>=b;i--)
#define MS0(a) memset(a,0,sizeof(a))
#define MS1(a) memset(a,-1,sizeof(a))
#define RI(a) scanf("%d",&a)
#define RII(a,b) scanf("%d%d",&a,&b)
#define RIII(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1

using namespace std;

typedef long long ll;
const int maxn=1000100;
const int INF=1<<29;

ll n;

int main()
{
    //freopen("in.txt","r",stdin);
    while(cin>>n){
        ll ans=0;
        if(n&1) ans=0;
        else{
            n/=2;
            if(n%2==0) ans=n/2-1;
            else ans=n/2;
        }
        cout<<ans<<endl;
    }
    return 0;
}
View Code

B题:

1<<29比1e9要小。。。以后INF就设为1e9+10好了。。。

#include<bits/stdc++.h>
#define REP(i,a,b) for(int i=a;i<=b;i++)
#define rep(i,a,b) for(int i=a;i>=b;i--)
#define MS0(a) memset(a,0,sizeof(a))
#define MS1(a) memset(a,-1,sizeof(a))
#define RI(a) scanf("%d",&a)
#define RII(a,b) scanf("%d%d",&a,&b)
#define RIII(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1

using namespace std;

typedef long long ll;
const int maxn=1000100;
const int INF=1e9+10;

int n,a[maxn];
int L[maxn];

int main()
{
   // freopen("in.txt","r",stdin);
    while(cin>>n){
        ll Min=INF;
        REP(i,1,n) RI(a[i]),Min=min(Min,a[i]*1ll);
        ll ans=0;
        ans+=1LL*Min*n;
        REP(i,1,n) a[i]-=Min;
        MS0(L);
        int f=0,l=0;
        REP(i,1,n){
            if(a[i]==0){
                f=i;break;
            }
        }
        rep(i,n,1){
            if(a[i]==0){
                l=i;break;
            }
        }
        int cur=f;
        REP(i,f+1,n){
            if(a[i]==0){
                L[i]=cur,cur=i;
            }
        }
        L[f]=l;
        ll tmp=0;
        REP(i,1,n){
            if(a[i]==0){
                if(L[i]<i) tmp=max(tmp,1LL*(i-L[i]-1));
                else tmp=max(tmp,1LL*(i-1+(n-L[i])));
            }
        }
        cout<<ans+tmp<<endl;
    }
    return 0;
}
View Code

C题:

这题不应该不会,因为紫书上见过有道题的构造方法和这个几乎一样。。。

#include<bits/stdc++.h>
#define REP(i,a,b) for(int i=a;i<=b;i++)
#define MS0(a) memset(a,0,sizeof(a))

using namespace std;

typedef long long ll;
const int maxn=1100;
const int INF=1e9+10;

int f[maxn][maxn];
int n,k;

void solve(int k)
{
    int n=1<<k;
    REP(i,1,n) REP(j,1,n) f[i][j+n]=f[i+n][j]=f[i][j],f[i+n][j+n]=!f[i][j];
}

int main()
{
    //freopen("in.txt","r",stdin);
    while(cin>>k){
        f[1][1]=1;
        REP(i,0,k-1) solve(i);
        n=1<<k;
        REP(i,1,n){
            REP(j,1,n){
                printf(f[i][j]?"+":"*");
            }
            puts("");
        }
    }
    return 0;
}
View Code

D题:

这题说实话,是之前没认真学的结果,其实扫描线也并非很难理解,写起来也不麻烦。

#include<bits/stdc++.h>
#define REP(i,a,b) for(int i=a;i<=b;i++)
#define MS0(a) memset(a,0,sizeof(a))
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1

using namespace std;

typedef long long ll;
const int maxn=300100;
const int INF=1e9+10;

int n;
int x,y,xt,yt;
struct Node
{
    int l,r;
};Node a[maxn];int an;
struct SegTree
{
    int sum,tag;
};SegTree T[maxn<<2];
struct Line
{
    int l,r,h;
    int tag;
    friend bool operator<(Line A,Line B)
    {
        return A.h<B.h;
    }
};Line line[maxn];int ln;
int X[maxn],Xn;

int binL(int l,int r,int x)
{
    while(l<=r){
        int m=(l+r)>>1;
        if(a[m].l==x) return m;
        if(a[m].l>x) r=m-1;
        else l=m+1;
    }
}

int binR(int l,int r,int x)
{
    while(l<=r){
        int m=(l+r)>>1;
        if(a[m].r==x) return m;
        if(a[m].r>x) r=m-1;
        else l=m+1;
    }
}

void push_up(int rt,int l,int r)
{
    if(T[rt].tag) T[rt].sum=a[r].r-a[l].l;
    else T[rt].sum=T[rt<<1].sum+T[rt<<1|1].sum;
}

void build(int l,int r,int rt)
{
    if(l==r){
        T[rt].sum=T[rt].tag=0;
        return;
    }
    int m=(l+r)>>1;
    build(lson);
    build(rson);
    push_up(rt,l,r);
}

void update(int L,int R,int tag,int l,int r,int rt)
{
    if(L<=l&&r<=R){
        T[rt].tag+=tag;
        if(T[rt].tag) T[rt].sum=a[r].r-a[l].l;
        else if(l==r) T[rt].sum=0;
        else T[rt].sum=T[rt<<1].sum+T[rt<<1|1].sum;
        return;
    }
    int m=(l+r)>>1;
    if(L<=m) update(L,R,tag,lson);
    if(R>m) update(L,R,tag,rson);
    push_up(rt,l,r);
}

int main()
{
    freopen("in.txt","r",stdin);
    while(cin>>n){
        Xn=ln=0;
        REP(i,1,n){
            scanf("%d%d%d%d",&x,&y,&xt,&yt);
            if(x>xt) swap(x,xt);
            if(y>yt) swap(y,yt);
            xt++;yt++;
            X[++Xn]=x;X[++Xn]=xt;
            line[++ln]={x,xt,y,1};
            line[++ln]={x,xt,yt,-1};
        }
        sort(line+1,line+ln+1);
        sort(X+1,X+Xn+1);
        Xn=unique(X+1,X+Xn+1)-(X+1);
        an=0;
        REP(i,1,Xn-1) a[++an]={X[i],X[i+1]};
        build(1,an,1);
        ll ans=0;
        REP(i,1,ln-1){
            int L=binL(1,an,line[i].l);
            int R=binR(1,an,line[i].r);
            update(L,R,line[i].tag,1,an,1);
            ans+=1LL*T[1].sum*(line[i+1].h-line[i].h);
        }
        cout<<ans<<endl;
    }
    return 0;
}
View Code

-------------------------------------------------------------

总之,继续刷dp,元旦前刷完第8章例题。

学个扫描线用了我一下午的时间,今天就不复习概率论了,明天到考试前开始复习+刷题模式,不然第8章就刷不完了,期末也很可能挂成一片。

 

posted @ 2015-12-28 16:54  __560  阅读(221)  评论(0编辑  收藏  举报