离散化

1.STL离散化
void LiSH(){
cin>>n;
for(int i=1;i<=n;i++)cin>>olda[i],newa[i]=olda[i];
sort(olda+1,olda+n+1);
int cnt=unique(olda+1,olda+n+1)-(
2.离散化+线段树
例题:HDU1199
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+255,M = 2.1e3+255,INF = 0x3f3f3f3f;
struct node{
int l,r,lmax,rmax,tmax,lazy;
}tr[N*4];
struct qi{
int a,b;
string s;
}q[M];
vector<int>num;
int n;
void pushup(int u){
tr[u].rmax=tr[u<<1|1].rmax;
if(tr[u<<1|1].lazy==-1)tr[u].rmax+=tr[u<<1].rmax;
tr[u].lmax=tr[u<<1].lmax;
if(tr[u<<1].lazy==-1)tr[u].lmax+=tr[u<<1|1].lmax;
tr[u].tmax=max(tr[u<<1].rmax+tr[u<<1|1].lmax,max(tr[u<<1].tmax,tr[u<<1|1].tmax));
if(tr[u<<1].lazy==tr[u<<1|1].lazy)tr[u].lazy=tr[u<<1].lazy;
else tr[u].lazy=0;
}
void build(int u,int l,int r){
if(l==r)tr[u]=(node){l,l,0,0,0,1};
else{
tr[u]=(node){l,r,0,0,0,1};
int mid=(l+r)>>1;
build(u<<1,l,mid);
build(u<<1|1,mid+1,r);
}
}
void pushdown(int u){
tr[u<<1].lazy=tr[u<<1|1].lazy=tr[u].lazy;
if(tr[u].lazy==1){
tr[u<<1].lmax=tr[u<<1].rmax=tr[u<<1].tmax=0;
tr[u<<1|1].lmax=tr[u<<1|1].rmax=tr[u<<1|1].tmax=0;
}else{
tr[u<<1].lmax=tr[u<<1].rmax=tr[u<<1].tmax=num[tr[u<<1].r-1]-num[tr[u<<1].l-2];
tr[u<<1|1].lmax=tr[u<<1|1].rmax=tr[u<<1|1].tmax=num[tr[u<<1|1].r-1]-num[tr[u<<1|1].l-2];
}
tr[u].lazy=0;
}
void modify(int u,int l,int r,int x){
if(tr[u].l>=l&&tr[u].r<=r){
tr[u].lazy=x;
if(x==1)tr[u].lmax=tr[u].rmax=tr[u].tmax=0;
else tr[u].lmax=tr[u].rmax=num[tr[u].r-1]-num[tr[u].l-2];
return;
}
if(tr[u].lazy!=0)pushdown(u);
int mid=(tr[u].l+tr[u].r)>>1;
if(l<=mid)modify(u<<1,l,r,x);
if(r>mid)modify(u<<1|1,l,r,x);
pushup(u);
}
int find(int x){
return lower_bound(num.begin(),num.end(),x)-num.begin()+1;
}
int query(int u,int x){
if(tr[u<<1].lmax==x)return num[tr[u].l-1];
if(tr[u].lazy)pushdown(u);
if(tr[u<<1].tmax==x)return query(u<<1,x);
if(tr[u<<1].rmax+tr[u<<1|1].lmax==x)return num[tr[u<<1].r-1]-tr[u<<1].rmax+1;
else return query(u<<1|1,x);
}
int main(){
while(cin>>n){
if(!n){
cout<<"Oh,my god\n";
continue;
}
num.clear();
for(int i=1;i<=n;i++){
cin>>q[i].a>>q[i].b>>q[i].s;
if(q[i].a>q[i].b)swap(q[i].a,q[i].b);
num.push_back(q[i].a);
num.push_back(q[i].b);
num.push_back(q[i].a-1);
num.push_back(q[i].a+1);
num.push_back(q[i].b-1);
num.push_back(q[i].b+1);
}
sort(num.begin(),num.end());
num.erase(unique(num.begin(),num.end()),num.end());
build(1,1,num.size());
for(int i=1;i<=n;i++){
int l=find(q[i].a),r=find(q[i].b);
if(q[i].s=="w")modify(1,l,r,-1);
else modify(1,l,r,1);
}
int x=tr[1].tmax;
if(!x)cout<<"Oh,my god\n";
else{
int y1=query(1,x),y2=y1+tr[1].tmax-1;
cout<<y1<<' '<<y2<<'\n';
}
}
return 0;
}
3.离散化+模拟
例题:HDU3634
注意换行哦~
#include<bits/stdc++.h>
#define ll unsigned long long
using namespace std;
const int N = 1e4+255,MOD = 1e9+7;
int a[N],b[N],L[N];
struct node{
int x1,y1,x2,y2,v;
}q[N];
bool cmp(node a,node b){
return a.v>b.v;
}
int T;
int main(){
cin>>T;
for(int o=1;o<=T;o++){
int n;
cin>>n;
int len=n*2;
for(int i=0;i<n;i++){
cin>>q[i].x1>>q[i].y1>>q[i].x2>>q[i].y2>>q[i].v;
a[i]=q[i].x1;
a[i+n]=q[i].x2;
b[i]=q[i].y1;
b[i+n]=q[i].y2;
}
sort(q,q+n,cmp);
sort(a,a+len);
sort(b,b+len);
ll ans=0;
for(int i=1;i<len;i++){
if(a[i]>a[i-1]){
for(int w=0;w<len-1;w++)L[w]=b[w+1]-b[w];
for(int l=0;l<n;l++){
if(q[l].x1<=a[i-1]&&q[l].x2>=a[i]){
ll d=0;
for(int w=0;w<len-1;w++){
if(q[l].y1<=b[w]&&q[l].y2>=b[w+1]){
d+=L[w];
L[w]=0;
}
}
ans+=((ll)(a[i]-a[i-1])*(ll)(d)*(ll)(q[l].v));
}
}
}
}
printf("Case %d: %lld\n",o,ans);
}
return 0;
}
/*
1
3
1 1 10 10 4
4 4 15 5 5
7 8 20 30 6
*/
4.离散化+差分
例题:HDU5124
这道题数据量很大,数组开不起,只能把数组转换成map数组来压缩空间
#include<bits/stdc++.h>
using namespace std;
const int N = 1e6+255;
struct point{
int l,r;
}p[N];
int T,n,a[N],dp[N];
map<int,int>mp;
int main(){
cin>>T;
while(T--){
int i,j;
mp=map<int,int>();
memset(a,0,sizeof(a));
memset(p,0,sizeof(p));
memset(dp,0,sizeof(dp));
cin>>n;
for(i=0,j=0;i<n;i++,j+=2){
cin>>p[i].l>>p[i].r;
a[j]=p[i].l;
a[j+1]=p[i].r;
}
sort(a,a+j);
int e=unique(a,a+j)-a;
for(int i=0;i<=e;i++)mp[a[i]]=i+1;
for(int i=0;i<n;i++){
dp[mp[p[i].l]]++;
dp[mp[p[i].r]+1]--;
}
int ans=0;
ans=dp[1];
for(int i=2;i<=e;i++){
dp[i]=dp[i]+dp[i-1];
ans=max(ans,dp[i]);
}
cout<<ans<<'\n';
}
return 0;
}
5.离散化+最大公约数+最小公倍数+线性DP
例题:HDU4028
这道题结合了一些数论知识,巧妙地结合了DP算法,进行求解=
#include<bits/stdc++.h>
#define ll long long
using namespace std;
map<ll,ll>d[55];
ll n,m,T;
ll gcd(ll a,ll b){
if(!b)return a;
return gcd(b,a%b);
}
ll lcm(ll a,ll b){
return a/gcd(a,b)*b;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
d[1][1]=1;
for(ll i=2;i<=40;i++){
d[i]=d[i-1];
d[i][i]++;
for(map<ll,ll>::iterator iter=d[i-1].begin();iter!=d[i-1].end();iter++){
int lcmab=lcm(i,iter->first);
d[i][lcmab]+=iter->second;
}
}
cin>>T;
for(ll k=1;k<=T;k++){
cin>>n>>m;
int ans=0;
for(map<ll,ll>::iterator iter=d[n].begin();iter!=d[n].end();iter++){
if(iter->first>=m)ans+=iter->second;
}
printf("Case #%d: %d\n",k,ans);
}
return 0;
}
6.离散化+STLset
例题:HDU5233
这道题运用了unique+lower_bound的STL离散化方法,在加上STL中的set进行计算
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+255,M = 2*N;
int h[N],q[N],s[M],n,m,cnt;
set<int>ans[M];
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
while(cin>>n>>m){
cnt=0;
for(int i=0;i<n;i++){
cin>>h[i];
s[cnt++]=h[i];
}
for(int i=0;i<m;i++){
cin>>q[i];
s[cnt++]=q[i];
}
sort(s,s+cnt);
cnt=unique(s,s+cnt)-s;
for(int i=0;i<cnt;i++)ans[i].clear();
for(int i=0;i<n;i++){
int d=lower_bound(s,s+cnt,h[i])-s;
ans[d].insert(i+1);
}
for(int i=0;i<m;i++){
int d=lower_bound(s,s+cnt,q[i])-s;
if(ans[d].empty())cout<<"-1\n";
else{
cout<<*ans[d].begin()<<'\n';
ans[d].erase(ans[d].begin());
}
}
}
return 0;
}

浙公网安备 33010602011771号