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>
大意,给你一幅 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;
}