Codeforces Round #368 (Div. 2)

A. Brain's Photo大水题

大意,给你一张照片的颜色,让你判断是黑白照(Y,G,B)还是彩色照(C,M,Y)

<span style="font-size:14px;">#include<math.h>
#include<algorithm>
#include<map>
#include<set>
#include<stack>
#include<queue>
#include<string.h>
#include<cstring>
#include<vector>
using namespace std;
#define INF 0x3f3f3f3f
#define mem(x,y) memset(x,y,sizeof(x))
typedef unsigned long long ULL;
typedef long long LL;
#define MX 5555555
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
typedef pair<int,int> PII;
int main() {
   // freopen("input.txt","r",stdin);
    int n,m;
    while(cin>>n>>m) {
        int sign=0;
        for(int i=1; i<=n; i++) {
            for(int j=1; j<=m; j++) {
                char s[2];
                scanf("%s",s);
                if(s[0]=='C'||s[0]=='M'||s[0]=='Y') sign=1;
<span style="white-space:pre">		</span>}
        }
        printf("%s\n",sign?"#Color":"#Black&White");
    }

    return 0;
}</span>


B. Bakery

大意,给你一幅 n个点的图,其中k个点有商店,要求你在没有商店的点中,选一点放置你的店铺使它里最近的一家商店的距离最短。

易得,你的店铺应放在某个商店旁,所以我们只要扫一遍商店旁的点,即可:


#include<iostream>
#include<cstdio>
#include<math.h>
#include<algorithm>
#include<map>
#include<set>
#include<stack>
#include<queue>
#include<string.h>
#include<cstring>
#include<vector>
using namespace std;
#define INF 0x3f3f3f3f
#define mem(x,y) memset(x,y,sizeof(x))
typedef unsigned long long ULL;
typedef long long LL;
#define MX 1111111
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
typedef pair<int,int> PII;
int n,m,k,rear,head[MX];
bool vis[MX];

struct Edge {
    int nxt,to,dist;
} edge[2*MX];
void edge_init() {
    rear=0;
    mem(head,-1);
    mem(vis,0);
}
void edge_add(int a,int b,int dist) {
    edge[rear].to=b;
    edge[rear].dist=dist;
    edge[rear].nxt=head[a];
    head[a]=rear++;
}
int main() {
   // freopen("input.txt","r",stdin);
    while(cin>>n>>m>>k) {

        edge_init();
        for(int i=1; i<=m; i++) {
            int a,b,dist;
            scanf("%d%d%d",&a,&b,&dist);
            edge_add(a,b,dist);
            edge_add(b,a,dist);
        }
        for(int i=1; i<=k; i++) {
            int x;
            scanf("%d",&x);
            vis[x]=1;
        }
        int ans=INF;

        for(int x=1; x<=n; x++) {
            if(vis[x]==0) continue;
            for(int i=head[x]; ~i; i=edge[i].nxt) {
                int v=edge[i].to;
                if(v==x) continue;
                if(vis[v]==0) {
                    ans=min(ans,edge[i].dist);
                }

            }
        }
        if(k==n||k==0) {
            printf("-1\n");
            continue;
        }
        printf("%d\n",ans==INF?-1:ans);


    }

    return 0;
}


C. Pythagorean Triples

大意,给你一个直角三角形得一条直角边,让你求另外2条边

设它给你的边为a,则  a^2+b^2=c^2 ---->a^2=c^2-b^2---->a^2=(c-b)*(c+b)

所以就是求a^2得一个因式分解d1,d2,使 d1+d2=2*c

所以,,d1+d2为偶数,,,所以要不d1与d2都为偶数,要不都为奇数。

对于a为偶数时,,a^2可以分解为2和另一个偶数得乘积

对于a为奇数,a^2可以分解为1和a^2这2个奇数得乘积,这样就构造出来了

注意,a为1,2得时候是不行得,,一开始特判一下就可以了

D. Persistent Bookcase

大意,有n个书架,每个有m个放书得位置,一开始全没书

有下列4个操作

1 i j 如果第i个书架得第j个位置中没有书,就在这里放书

2 i j 如果第i个书架得第j个位置中有书,就把书拿掉

3 i 将第i得书架,有书得位置拿掉书,没书得位置添上书

4 k 将书架还原成执行完k个操作得状态

每个操作后都输出,执行完当前操作后,书架得总书数

如果没有4操作,我们完全可以用线段树

因为4操作需要还原状态,我们可以将操作建成一颗树,对于不是4的操作,我们将改操作链接在上一个操作之后。对于是4的操作,我们将改操作链接在k这个操作之后。

这样就建成了一棵树,最后前序遍历一次,就好了,,细节自己想把

#include<iostream>
#include<cstdio>
#include<math.h>
#include<algorithm>
#include<map>
#include<set>
#include<bitset>
#include<stack>
#include<queue>
#include<string.h>
#include<cstring>
#include<vector>
using namespace std;
#define INF 0x3f3f3f3f
#define mem(x,y) memset(x,y,sizeof(x))
typedef unsigned long long ULL;
typedef long long LL;
#define MX 1000
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
typedef pair<int,int> PII;
bitset<MX+1> BIT[MX+1],C;
int rear=0,head[MX*111],ans[111*MX+5];
int n,m,q;
struct Edge {
    int nxt,i,j,id;
    int sign;
} edge[MX*111];
void edge_init() {
    rear=1;
    mem(head,-1);
}
void edge_add(int a,int i,int j,int k) {
    edge[rear].nxt=head[a];
    edge[rear].i=i;
    edge[rear].j=j;
    edge[rear].sign=k;
    head[a]=rear++;
}
void dfs(int u) {
    for(int i=head[u]; ~i; i=edge[i].nxt) {
        if(edge[i].sign==1) {
            bool flag=0;
            if(BIT[edge[i].i][edge[i].j]==0) {
                BIT[edge[i].i][edge[i].j]=1;
                flag=1;
                ans[i]=ans[u]+1;
            } else ans[i]=ans[u];
            dfs(i);
            if(flag) {
                BIT[edge[i].i][edge[i].j]=0;
            }
        } else if(edge[i].sign==2) {
            bool flag=0;
            if(BIT[edge[i].i][edge[i].j]==1) {
                BIT[edge[i].i][edge[i].j]=0;
                flag=1;
                ans[i]=ans[u]-1;
            } else ans[i]=ans[u];
            dfs(i);
            if(flag) {
                BIT[edge[i].i][edge[i].j]=1;
            }
        } else if(edge[i].sign==3) {
            ans[i]=ans[u]-BIT[edge[i].i].count();
            BIT[edge[i].i]^=C;;
            ans[i]+= BIT[edge[i].i].count();
            dfs(i);
            BIT[edge[i].i]^=C;
        } else  ans[i]=ans[u],dfs(i);
    }
}
int main() {
   // freopen("input.txt","r",stdin);
    while(~scanf("%d%d%d",&n,&m,&q)) {
        edge_init();
        for(int i=1; i<=m; i++) C[i]=1;
        for(int w=1; w<=q; w++) {
            int k,i,j;
            scanf("%d%d",&k,&i);
            if(k==1||k==2) {
                scanf("%d",&j);
                edge_add(w-1,i,j,k);
            } else {
                if(k==4)edge_add(i,0,0,k);
                else edge_add(w-1,i,0,k);
            }
        }
        dfs(0);
        for(int i=1; i<=q; i++) printf("%d\n",ans[i]);
    }
    return 0;
}


E. Garlands

大意,,有一个n*m的矩阵,矩阵里面有k条链,然后有q次询问,每次询问可以使得一条链状态取反,变成0,或者使这条链变成原来的值,。然后查询(ASK)一个矩阵的权值和。

这题,,数据略水,,,树状数组在线xjb搞搞就可以过。。

感觉数据严一点地话就要离线做了。。。


#include<iostream>
#include<cstdio>
#include<math.h>
#include<algorithm>
#include<map>
#include<set>
#include<stack>
#include<queue>
#include<string.h>
#include<cstring>
#include<vector>
using namespace std;
#define INF 0x3f3f3f3f
#define mem(x,y) memset(x,y,sizeof(x))
typedef unsigned long long ULL;
typedef long long LL;
#define MX 2222
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
typedef pair<LL,LL> PII;
LL n,m,k;
LL tree[MX][MX],num[MX],a[MX][MX],b[MX][MX],w[MX][MX];
bool isok[MX],flag[MX];
LL low_bit(LL x) {
    return x&-x;
}
void tree_add(LL x,LL y,LL v) {
//cout<<v<<endl;
    for(LL i=x; i<=n; i+=low_bit(i))
        for(LL j=y; j<=m; j+=low_bit(j)) tree[i][j]+=v;
}
LL tree_sum(LL x,LL y) {
    LL sum=0;
    for(LL i=x; i; i-=low_bit(i))
        for(LL j=y; j; j-=low_bit(j)) sum+=tree[i][j];
    return sum;
}
int main() {
    freopen("input.txt","r",stdin);
    scanf("%I64d%I64d%I64d",&n,&m,&k);
    for(LL i=1; i<=k; i++) {
        scanf("%I64d",&num[i]);
        for(LL j=1; j<=num[i]; j++) {
            scanf("%I64d%I64d%I64d",&a[i][j],&b[i][j],&w[i][j]);
        }
    }
    LL q;
    scanf("%I64d",&q);
    mem(flag,0);
    mem(isok,1);
    for(LL i=1; i<=q; i++) {
        char s[10];
        scanf("%s",s);
        if(s[0]=='A') {
            LL x1,x2,y1,y2;
            scanf("%I64d%I64d%I64d%I64d",&x1,&y1,&x2,&y2);
            for(LL i=1; i<=k; i++) {
                if(isok[i]) {
                    for(LL j=1; j<=num[i]; j++) tree_add(a[i][j],b[i][j],w[i][j]*(flag[i]?-1:1));
                    flag[i]^=1;
                }
            }
            printf("%I64d\n",tree_sum(x2,y2)-tree_sum(x2,y1-1)-tree_sum(x1-1,y2)+tree_sum(x1-1,y1-1));
            mem(isok,0);
        } else {
            LL e;
            scanf("%I64d",&e);
            isok[e]^=1;
        }
    }
return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值