标签:mes return 前缀 while tchar 之间 mod n+1 排序
期望得分 200
实际得分 174
话说这个第三题sub都没有... 不好骗分啊
A 排 座位
( ( arrange .pas/c/cpp)
【问题描述】
信竞队有 n 名队员,竞赛机房有一张长桌,上面一字排开有 n 台电脑,供同学们坐成一
排使用。每学期开始前,老师都要给同学们排座位。
同学之间存在仰慕(膜拜)关系,如 A 同学仰慕 B 同学,那么 A 同学就要求座位必须与 B
同学相邻。同学之间存在 m 对仰慕关系。老师想要找到使得所有同学的要求都得到满足座位
安排方案。请你帮忙计算合法方案的总数,答案可能很大,mod 989999 后再输出。
主要说一下判环的问题
首先注意到一条边的环只用在读入的时候判断一下就行了
然后对于环不是一条边的情况 我们只需要在加进集合里的时候判断是不是在一个集合就行了
也可以用top排序求环
//
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mod 989999
#define maxnn 1000010
typedef pair<int,int > P;
map<P,int > mm;
ll n,m;
int r[maxnn];
int f[maxnn];
int ru[maxnn];
ll cnt1=1,cnt2;
ll size[maxnn];
#define GC getchar()
inline ll R()
{
char t;
ll f=1;
ll x=0;
t=GC;
while(!isdigit(t)) {if(t=='-') f=-1;t=GC;}
while(isdigit(t))
{
x=x*10+t-'0';
t=GC;
}
return x*f;
}
int gf(int v)
{
return f[v]==v?v:f[v]=gf(f[v]);
}
ll jie(ll v)
{
ll tmp=1;
for(int i=1;i<=v;i++)
{
tmp=(tmp*i)%mod;
}
return tmp%mod;
}
void FIE()
{
freopen("arrange.in","r",stdin);
freopen("arrange.out","w",stdout);
}
int main()
{
//FIE();
n=R();
m=R();
ll x,y;
for(int i=1;i<=n;i++)
{
f[i]=i;
size[i]=1;
}
for(int i=1;i<=m;i++)
{
x=R();
r[x]=R();
int y=r[x];
if(r[r[x]]==x) continue;
ru[y]++;
ru[x]++;
if(ru[x]>2||ru[y]>2)
{
puts("0");
return 0;
}
int fx=gf(x);
int fy=gf(y);
if(fx!=fy)
{
size[fy]+=size[fx];
f[fx]=fy;
}
else
{
puts("0");
return 0;
}
}
for(int i=1;i<=n;i++)
{
if(f[i]==i)
{
if(size[i]>1) cnt1=(cnt1*2)%mod;;
cnt2++;
}
}
cout<<(jie(cnt2)*cnt1)%mod;
}
B 数列截段
时间限制 : - MS 空间限制 : - KB
评测说明 : 1s,256m
问题描述
老师给出一个长度为N的整数数列A。现在要求你在A中截取一段连续子序列,使得该区间的数字总和不小于X,并且不大于Y。问总共有多少种不同的截取方式?
想到用前缀和+树状数组离散化
式子可以表示为 x<=sum[j]-sum[i-1]<=y
先求x<=sum[j]-sum[i-1] 然后容斥一下减去y<sum[j]-sum[i-1]的方案之和即为答案
code:
//
#include<bits/stdc++.h>
using namespace std;
#define maxnn 500000
#define ll long long
#define lowbit(i) i&(-i)
ll sum[maxnn];
ll n,x,y;
int id[maxnn];
ll zh[maxnn];
ll c[maxnn];
ll tr=0;
#define GC getchar()
inline ll R()
{
char t;
ll f=1;
ll x=0;
t=GC;
while(!isdigit(t)) {if(t=='-') f=-1;t=GC;}
while(isdigit(t))
{
x=x*10+t-'0';
t=GC;
}
return x*f;
}
void add(int x)
{
for(int i=x;i<=3*n+100000;i+=lowbit(i))
{
c[i]++;
}
}
ll get(int x)
{
ll ans=0;
for(int i=x;i;i-=lowbit(i))
{
ans+=c[i];
}
return ans;
}
void FIE()
{
freopen("cutout.in","r",stdin);
freopen("cutout.out","w",stdout);
}
int main()
{
//FIE();
ll t=0;
ll ans=0;
n=R();
x=R();
y=R();
for(int i=1;i<=n;i++)
{
t=R();
sum[i]=sum[i-1]+t;
tr++;
sum[n+tr]=sum[i]-x;
tr++;
sum[n+tr]=sum[i]-y;
zh[i]=sum[i];
}
sort(sum,sum+1+n+tr);
int r=unique(sum,sum+1+n+tr)-sum-1;
for(int i=0;i<=n;i++)
{
id[i]=lower_bound(sum,sum+1+r,zh[i])-sum+1;
}
for(int i=0;i<=n;i++)
{
ll tmp1=lower_bound(sum,sum+1+r,zh[i]-x)-sum+1;
ans+=get(tmp1);
ll tmp2=lower_bound(sum,sum+1+r,zh[i]-y)-sum+1;
ans=ans-get(tmp2-1);
add(id[i]);
}
printf("%lld",ans);
}
标签:mes return 前缀 while tchar 之间 mod n+1 排序
原文地址:https://www.cnblogs.com/OIEREDSION/p/11665890.html