我是咸鱼
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:
",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
",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);
}