%%%Manchery
给每个区间随机一个权值,这样每个位置被哪些区间覆盖奇数次就可以用区间权值的xor值表示,假设为x,一个区间被哪些区间覆盖也可以用xor值表示,假设为y
那么满足x=y的区间就是符合条件的区间
前缀和搞一搞,map记一记就好啦
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
#define N 200010
using namespace std;
typedef unsigned long long ull;
typedef pair<ull,ull> paru;
int n,m;
long long ans;
int l[N],r[N],num[N];
ull p1[N],p2[N];
vector<ull> s1[N],t1[N],s2[N],t2[N];
map<paru,long long> M,S;
inline char nc(){
static char buf[100000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline void rea(int &x){
char c=nc(); x=0;
for(;c>'9'||c<'0';c=nc());for(;c>='0'&&c<='9';x=x*10+c-'0',c=nc());
}
inline long long calc(int x){
return 1ll*(x+1)*x*x/2-1ll*(x-1)*x/2-1ll*x*(x-1)*(2*x-1)/6;
}
int main(){
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
rea(n); rea(m);
for(int i=1;i<=n;i++){
rea(l[i]); rea(r[i]);
ull hash1=1ULL*rand()*rand()*rand(),hash2=1ULL*rand()*rand()*rand();
s1[l[i]].push_back(hash1); s2[l[i]].push_back(hash2);
t1[r[i]].push_back(hash1); t2[r[i]].push_back(hash2);
p1[l[i]]^=hash1; p1[r[i]+1]^=hash1;
p2[l[i]]^=hash2; p2[r[i]+1]^=hash2;
num[l[i]]++; num[r[i]+1]--;
}
for(int i=1;i<=m;i++) p1[i]^=p1[i-1],p2[i]^=p2[i-1];
for(int i=1;i<=m;i++) p1[i]^=p1[i-1],p2[i]^=p2[i-1];
ull a1=0,b1=0,a2=0,b2=0;
M[paru(0,0)]=1;
for(int i=1;i<=m;i++){
for(int x=0;x<s1[i].size();x++) a1^=s1[i][x],a2^=s2[i][x];
ans+=M[paru(a1^p1[i],a2^p2[i])]*i-S[paru(a1^p1[i],a2^p2[i])];
for(int x=0;x<t1[i].size();x++) b1^=t1[i][x],b2^=t2[i][x];
M[paru(b1^p1[i],b2^p2[i])]++; S[paru(b1^p1[i],b2^p2[i])]+=i;
}
for(int i=1;i<=m;i++) num[i]+=num[i-1];
for(int i=1,j;i<=m;i=j+1){
j=i;
while(j<=m&&num[j]==0) j++;
j--;
if(j<i) j=i;
else ans-=calc(j-i+1);
}
printf("%I64d\n",ans);
return 0;
}