2018.7.13模拟赛

我是咸鱼

T1
图论题。。。。我竟然只写了暴力○| ̄|_
sol:我好懒啊

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#define int long long
using namespace std;
const int N=100005;
int n,m,d[N],ani[N],vis[N],fa[N],ans,head[N],ecnt,tim,siz[N];
struct Edge{
	int v,u,val;
}ed[1000005];
int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}
bool cmp(Edge x,Edge y) {return x.val>y.val;}
void klskr() {
	int cnt=0;
	for(int i=1;i<=m;i++) {
		int u=find(ed[i].v),v=find(ed[i].u);
		if(u!=v) {
			ans+=ed[i].val*(siz[u]*siz[v]);
			siz[u]+=siz[v];
			fa[v]=u;
			cnt++;
			if(cnt==n-1) return;
		}
	}
}
signed main() {
	freopen("zoo.in","r",stdin);
	freopen("zoo.out","w",stdout);
	scanf("%d%d",&n,&m);
	for(int i=0;i<=n;i++) fa[i]=i,siz[i]=1;
	for(int i=1; i<=n; i++) scanf("%d",&ani[i]);
	for(int i=1,a,b; i<=m; i++) {
		scanf("%d%d",&a,&b);
		ed[i].u=a,ed[i].v=b,ed[i].val=min(ani[a],ani[b]);
	}
	sort(ed+1,ed+1+m,cmp);
	klskr();
	cout<<ans*2;
}

T2
好不容易A了。。。
sol:我好懒啊

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=400005,inf=0x3f3f3f3f;
int T,n,a[200005],b[N],c[N],cnt,opt[200005],t1[N],t2[N],kase,tt;
void add1(int pos,int c) {
	for(int i=pos;i<=cnt;i+=i&-i) 
	t1[i]+=c;
}
void add2(int pos,int c) {
	for(int i=pos;i<=cnt;i+=i&-i)
	t2[i]+=c;
}
int ask1(int l,int r) {
	int res=0;
	for(int i=r;i;i-=i&-i)
	res+=t1[i];
	for(int i=l-1;i;i-=i&-i)
	res-=t1[i];
	return res;
}
int ask2(int l,int r) {
	int res=0;
	for(int i=r;i;i-=i&-i)
	res+=t2[i];
	for(int i=l-1;i;i-=i&-i)
	res-=t2[i];
	return res;
}
int main() {
	freopen("segment.in","r",stdin);
	freopen("segment.out","w",stdout);
	scanf("%d",&T);
	while(T--) {
		kase++;
		printf("Case #%d:\n",kase);
		scanf("%d",&n);
		cnt=0;
		memset(t1,0,sizeof t1);
		memset(t2,0,sizeof t2);
		for(int i=1; i<=n; i++) {
			scanf("%d%d",&opt[i],&a[i]);
			if(!opt[i])
				b[++cnt]=a[i],c[cnt]=a[i],b[++cnt]=a[i]+cnt/2,c[cnt]=a[i]+cnt/2;
		}
		sort(b+1,b+1+cnt);
		int u=unique(b+1,b+1+cnt)-b-1;
		for(int i=1; i<=cnt; i++) {
			c[i]=lower_bound(b+1,b+1+u,c[i])-b;
		}
		cnt=u;
		tt=0;
		for(int i=1;i<=n;i++) {
			if(opt[i]==1) {
				add1(c[a[i]*2-1],-1);
				add2(c[a[i]*2],-1);
			}
			else {
				tt++;
				printf("%d\n",ask1(c[tt],cnt)-ask2(c[tt+1]+1,cnt));
				add1(c[tt],1);
				add2(c[++tt],1);
			}
		}
	}
}

T3
sol:
数学题,因为严格限制k<max(n,m),所以可以知道至少有一行空的,再判一下已经填满的格子里有没有一行已经宣判不行的即可。
我好懒啊

#include <iostream>
#include <cstdio>
#define int long long 
using namespace std;
const int N=1000005;
int n,m,k,lin[N],row[N],mod,pos,val[N];
bool flag=0;
int ksm(int d,int z) {
	int res=1ll;
	while(z) {
		if(z&1) res*=d,res%=mod;
		d*=d,d%=mod;z>>=1ll;
	}
	return res;
}
signed main() {
	freopen("number.in","r",stdin);
	freopen("number.out","w",stdout);
	scanf("%lld%lld%lld",&n,&m,&k);
	if(n<m) swap(n,m),flag=1;//一开始我不知道这句话有什么用,直到我被一个1*10的矩阵卡了。。。
	if((n&1ll)!=(m&1ll)) {
		puts("0");return 0;
	}
	for(int i=1;i<=n;i++) val[i]=1;
	for(int i=1,a,b,c; i<=k; i++) {
		scanf("%lld%lld%lld",&a,&b,&c);
		if(flag) swap(a,b);
		row[a]++,val[a]*=c;
	}
	scanf("%lld",&mod);
	for(int i=1;i<=n;i++) if(row[i]==m&&val[i]==1) return puts("0"),0;
	long long ans=1ll;
	for(int i=1;i<=n;i++) if(!row[i])swap(row[i],row[n]),swap(val[i],val[n]);
	for(int i=1;i<n;i++) if(row[i]<m) ans*=ksm(2ll,m-row[i]-1),ans%=mod;
	printf("%lld",ans);
}

posted @ 2018-07-13 19:29  SWHsz  阅读(99)  评论(0编辑  收藏  举报