就是给题目中给出的每个区间随一个值 然后判断一个区间是否合法 把区间内所有数xor和 再xor上 区间中出现过的所有数的xor和 为 0
前缀和统计下
本人脸黑 单hash交了好几发都是WA 迫不得已双hash
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<map>
#include<ctime>
#define pb push_back
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
typedef pair<ull,ull> abcd;
inline ll sum(ll n){ return n*(n+1)/2;}
inline ll sum2(ll n){ return n*(n+1)*(2*n+1)/6;}
inline ll calc(ll n){ return (n+1)*sum(n)-sum2(n);}
const int N=200005;
#define read(x) scanf("%d",&(x))
int n,m;
int l[N],r[N];
vector<int> L[N],R[N];
ull h1[N],h2[N],a[N],b[N];
map<abcd,ll> F,G;
ll ans;
int cnt[N];
int main(){
srand(time(0));
freopen("t.in","r",stdin);
freopen("t.out","w",stdout);
read(n); read(m);
for (int i=1;i<=n;i++){
read(l[i]); read(r[i]);
L[l[i]].pb(i); R[r[i]].pb(i);
a[i]=(ull)rand()*rand()*rand()*rand()*rand();
b[i]=(ull)rand()*rand()*rand()*rand()*rand();
h1[l[i]]^=a[i]; h1[r[i]+1]^=a[i];
h2[l[i]]^=b[i]; h2[r[i]+1]^=b[i];
cnt[l[i]]++; cnt[r[i]+1]--;
}
for (int i=1;i<=m;i++) h1[i]^=h1[i-1],h2[i]^=h2[i-1];
for (int i=1;i<=m;i++) h1[i]^=h1[i-1],h2[i]^=h2[i-1];
G[abcd(0,0)]++; F[abcd(0,0)]=0;
ull s1=0,s2=0,t1=0,t2=0;
for (int i=1;i<=m;i++){
for (int x:L[i]) s1^=a[x],s2^=b[x];
ans+=G[abcd(s1^h1[i],s2^h2[i])]*i-F[abcd(s1^h1[i],s2^h2[i])];
for (int x:R[i]) t1^=a[x],t2^=b[x];
F[abcd(t1^h1[i],t2^h2[i])]+=i; G[abcd(t1^h1[i],t2^h2[i])]++;
}
for (int i=1;i<=m;i++) cnt[i]+=cnt[i-1];
for (int i=1;i<=m;)
if (cnt[i]==0){
int j=i; while (j+1<=m && cnt[j+1]==0) j++;
ans-=calc(j-i+1);
i=j+1;
}else
i++;
printf("%I64d\n",ans);
return 0;
}