洛谷 U140761 绅士品位
洛谷 U140761 绅士品位
题目背景
虽然SeawaySeawa**y在日常服装上不拘小节,但是SeawaySeawa**y自我感觉自己是非常有生活品位的绅士。并且,他不屑与品位低的人为伍。这样,SeawaySeawa**y的周围就有了一群像SeawaySeawa**y一样绅士的朋友,SeawaySeawa**y和他们相处得很开心。但是,生活中总会有不愉快:这些朋友同样不喜欢和品位低的人为伍,并且,自负地,他们只会以自己的品位作为标准衡量他人。于是,当SeawaySeawa**y要办派对的时候,就会很头疼:他必须不能同时邀请某一个人和不屑与之为伍的其他人。
题目描述
在SeawaySeawa**y和他的朋友们眼中,有NN种行为被公认为有品位的绅士行为。但人无完人,不可能有人能同时具有这NN种行为。更特殊地,每个绅士会从这NN种行为中挑选仅55种行为,作为代表他个人品位的绅士行为。两个绅士可以为伍,当且仅当代表他们各自个人品位的55种行为中,至少有一种行为是一致的。现在,SeawaySeawa**y想知道,在他的MM个绅士朋友中,有多少对绅士是不能被同时邀请出席派对的。我们定义:两对人不同,当且仅当其中有至少一个人不同。
输入格式
从文件gentleman.ingentleman.i**n中读入数据。
第一行包括两个正整数NN和MM。NN表示绅士行为总数,这些行为从1-N1−N编号。MM表示接下来的SeawaySeawa**y的绅士朋友数量。接下来的MM行,每行五个整数。描述代表一个绅士个人品位的五种行为。
输出格式
输出到文件gentleman.outgentleman.out中。
一行一个整数,表示SeawaySeawa**y不能同时被邀请出席派对的绅士对数量。由于答案可能很大,请输出其对998244353998244353取模的结果。
题解:
时空互换。
暴力可过。
稍稍优化。
代码:
#include<cstdio>
#include<bitset>
#include<algorithm>
#define ll long long
using namespace std;
const int maxn=50000+10;
const int maxm=250000+10;
int a[maxn][5],vis[maxn],mp[maxm],tot;
ll ans;
int n,m;
bitset<maxn+10> s[10010],t[10010];
void solve(int l,int r,int x,int y)
{
for(int i=x;i<=y;i++)
t[i-x].reset();
for(int i=l;i<=n;i++)
for(int j=0;j<5;j++)
if(x<=a[i][j]&&a[i][j]<=y)
t[a[i][j]-x][i]=1;
for(int i=l;i<=r;i++)
{
for(int j=0;j<5;j++)
if(x<=a[i][j]&&a[i][j]<=y)
t[a[i][j]-x][i]=0;
for(int j=0;j<5;j++)
if(x<=a[i][j]&&a[i][j]<=y)
if(!vis[i])
s[i-l]=t[a[i][j]-x],vis[i]=1;
else
s[i-l]|=t[a[i][j]-x];
}
}
int main()
{
//freopen("gentleman.in","r",stdin);
//freopen("gentleman.out","w",stdout);
scanf("%d",&n);
for(int i=1;i<=n;i++)
for(int j=0;j<5;j++)
{
int x;
scanf("%d",&x);
a[i][j]=mp[++tot]=x;
}
sort(mp+1,mp+tot+1);
tot=unique(mp+1,mp+tot+1)-(mp+1);
for(int i=1;i<=n;i++)
for(int j=0;j<5;j++)
a[i][j]=lower_bound(mp+1,mp+tot+1,a[i][j])-mp;
for(int l=1,r;l<=n;l+=10000)
{
r=min(l+9999,n);
for(int x=1,y;x<=tot;x+=10000)
{
y=min(x+9999,tot);
solve(l,r,x,y);
}
for(int i=l;i<=r;i++)
ans+=s[i-l].count();
}
ans=1ll*n*(n-1ll)/2ll-ans;
printf("%lld\n",ans);
return 0;
}