题解:P11615 【模板】哈希表
Soviet_Onion · · 题解
P11615 【模板】哈希表
暴力思路
第一眼看到题面,立刻使用了 STL 中的 map 按题意进行映射。代码实现非常简单。时间复杂度约为
#include<iostream>
#include<unordered_map>
#define ll unsigned long long
using namespace std;
unordered_map<ll,ll>m;
int n;
ll x,y,ans;
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%llu%llu",&x,&y);
ans+=i*m[x];
m[x]=y;
}
printf("%llu\n",ans);
return 0;
}
结果也一样简洁明了:鲜艳的 TLE。
优化
可以使用另一种映射 unordered_map,可以减小常数。
但是结果一样,仍然超时。
正解:在线哈希表
哈希表,就是对于上述思路的优化。题目中给定的
所以我们需要开
这样的时间复杂度是
注意
#include<iostream>
#include<unordered_map>
#define ll unsigned long long
#define getchar() (tt==ss&&(tt=(ss=In)+fread(In,1,1<<20,stdin),ss==tt)?EOF:*ss++)
using namespace std;
char In[1<<20],*ss=In,*tt=In;
const int N=1e6+10;
const int P=1e6+3;
ll read(void){ll f=1,res=0;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){res=res*10+(ch-'0');ch=getchar();}return res*f;}
void write(ll x){if(x<0){putchar('-');x=-x;}if(x>=10) write(x/10);putchar((x%10)+'0');return;}
unordered_map<ll,ll>m[N];
ll a,b,r,ans;
int n;
int main(){
n=read();
for(int i=1;i<=n;i++){
a=read(),b=read();
r=a%P;
ans+=i*m[r][a];
m[r][a]=b;
}
write(ans),putchar('\n');
return 0;
}
离线做法
非常简单且跑得飞快。
先读入所有询问,然后以
#include<iostream>
#include<vector>
#include<algorithm>
#include<cmath>
#define pb push_back
#define ll unsigned long long
#define getchar() (tt==ss&&(tt=(ss=In)+fread(In,1,1<<20,stdin),ss==tt)?EOF:*ss++)
using namespace std;
char In[1<<20],*ss=In,*tt=In;
const int N=5e6+10;
struct Node1{
ll x;
ll y;
int id;
friend bool operator <(const Node1 a,const Node1 b){
if(a.x!=b.x) return a.x<b.x;
return a.id<b.id;
}
}a[N];
struct Node2{
ll ans;
int id;
friend bool operator <(const Node2 a,const Node2 b){
return a.id<b.id;
}
}b[N];
int n;
ll res;
ll read(void){ll f=1,res=0;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){res=res*10+(ch-'0');ch=getchar();}return res*f;}
int main(){
n=read();
for(int i=1;i<=n;i++){
a[i].x=read();
a[i].y=read();
a[i].id=i;
}
sort(a+1,a+n+1);
for(int i=1;i<=n;){
int l=i,r=i;
while(i<=n&&a[r].x==a[l].x) r=++i;
r--;
for(int j=l;j<=r;j++) b[j]={(j-1<l?0ll:a[j-1].y),a[j].id};
}
sort(b+1,b+n+1);
for(int i=1;i<=n;i++){
res+=i*b[i].ans;
}
printf("%llu\n",res);
return 0;
}