【离散化算法】
注:只是新手的笔记,慎看!!!欢迎大佬指错
问题引入:

感觉?...感觉可以模拟n次操作,再取前缀和啊
但是 l 和 r 可以取到1e9,显然不行
这时便可以使用离散化!
可以观察到虽然 l r 可以取到1e9,但是n只有1e5,所以显然只有一部分的点可以被操作到,我们就可以只关注那些被操作的,用一个数组记录下来
比如输入x1=1 c1=2,x2=3 c2=2,x3=3 c3=4, x4=7 c4=5
我们发现只有1,3,7被操作了,所以我们先存1,3,3,7 然后去重就能得到被操作的数
这样我们就可以将时间复杂度降到 n 了
代码:(推荐好文中有详解)
cpp
#include <bits/stdc++.h>
#define int long long
#define all(x) begin(x),end(x)
using namespace std;
void solve()
{
int n,m;
cin>>n>>m;
vector <pair<int,int>> pr,rl;
vector <int> pos,s(300005),a(300005);//x,l,r都要存,所以开3e5
for(int i=1;i<=n;i++)
{
int x,c;
cin>>x>>c;
pr.push_back({x,c});
pos.push_back(x);
}
for(int i=1;i<=m;i++)
{
int l,r;
cin>>l>>r;
rl.push_back({l,r});
pos.push_back(l);
pos.push_back(r);
}
sort(all(pos));
pos.erase(unique(all(pos)),pos.end());//排序去重
for(auto x:pr )
{
int t=x.first;
auto it=lower_bound(pos.begin(),pos.end(),t)-pos.begin();//二分找到该数下标
a[it]+=x.second;
}
s[0]=a[0];
for(int i=1;i<=pos.size();i++)//前缀和
{
s[i]=s[i-1]+a[i];
}
for(auto x:rl )
{
int l=x.first;
int r=x.second;
auto it=lower_bound(all(pos),l)-pos.begin();
auto ip=lower_bound(all(pos),r)-pos.begin();
if(it==0)
{
cout<<s[ip]<<endl;
}else cout<<s[ip]-s[it-1]<<endl;
}
}
【离散化 + 差分】


简述:给定三维空间中 n 条线段,所有线段端点都在给定长方体表面上。求:存在一个垂直于某条坐标轴的平面,最多能与多少条线段相交。线段与平面相交的定义:线段与平面存在至少一个公共点。
我们分析单一维度x轴

就是说重叠线段最多的是多少,这里明显是3
这里第一思路是差分,但是可以到1e9,不行,所以要离散化
我们对要操作的点记录下来,再进行差分
思路和上题差不多,但是要掌握差分
代码:可以用函数,但是我当时没注意
cpp
#include <bits/stdc++.h>
#define int long long
#define all(x) begin(x),end(x)
using namespace std;
int n,a,b,c;
vector <pair<int,int>> xy1,xy2,xy3;
vector <int> h(200005),pos,s(200005);
void solve()
{
cin>>n>>a>>b>>c;
for(int i=0;i<n;i++)
{
int x1,y1,z1,x2,y2,z2;
cin>>x1>>y1>>z1>>x2>>y2>>z2;
xy1.push_back({x1,x2});
xy2.push_back({y1,y2});
xy3.push_back({z1,z2});
}
//xy1
for(auto p:xy1 )
{
int x=p.first;
int y=p.second;
pos.push_back(x);
pos.push_back(y);
}
sort(all(pos));
pos.erase(unique(all(pos)),pos.end());
for(auto p:xy1 )
{
int x=p.first;
int y=p.second;
if(x>y) swap(x,y);
int it=lower_bound(all(pos),x)-pos.begin();
int ip=lower_bound(all(pos),y)-pos.begin();
h[it]++;
h[ip+1]--;
}
s[0]=h[0];
for(int i=1;i<pos.size()+100;i++)
{
s[i]=s[i-1]+h[i];
}
int cns_1=-1;
for(auto x:s )
{
cns_1=max(cns_1,x);
}
fill(all(s),0);
pos.clear();
fill(all(h),0);
//xy2
for(auto p:xy2 )
{
int x=p.first;
int y=p.second;
pos.push_back(x);
pos.push_back(y);
}
sort(all(pos));
pos.erase(unique(all(pos)),pos.end());
for(auto p:xy2 )
{
int x=p.first;
int y=p.second;
if(x>y) swap(x,y);
int it=lower_bound(all(pos),x)-pos.begin();
int ip=lower_bound(all(pos),y)-pos.begin();
h[it]++;
h[ip+1]--;
}
s[0]=h[0];
for(int i=1;i<pos.size()+100;i++)
{
s[i]=s[i-1]+h[i];
}
int cns_2=-1;
for(auto x:s )
{
cns_2=max(cns_2,x);
}
fill(all(s),0);
pos.clear();
fill(all(h),0);
//xy3
for(auto p:xy3 )
{
int x=p.first;
int y=p.second;
pos.push_back(x);
pos.push_back(y);
}
sort(all(pos));
pos.erase(unique(all(pos)),pos.end());
for(auto p:xy3 )
{
int x=p.first;
int y=p.second;
if(x>y) swap(x,y);
int it=lower_bound(all(pos),x)-pos.begin();
int ip=lower_bound(all(pos),y)-pos.begin();
h[it]++;
h[ip+1]--;
}
s[0]=h[0];
for(int i=1;i<pos.size()+100;i++)
{
s[i]=s[i-1]+h[i];
}
int cns_3=-1;
for(auto x:s )
{
cns_3=max(cns_3,x);
}
cout<<max({cns_1,cns_2,cns_3});
}
signed main()
{
int t=1;
//cin>>t;
while(t--)
{
solve();
}
return 0;
}