模拟+数据结构:上海省选2013 P3998题解
P3998 [SHOI2013] 发微博
01.题意理解
进行\(m\)次操作,操作分为\(3\)种:
\(01.发布一条说说\)
\(02.和另一个用户建立朋友关系\)
\(03.和另一个用户解除朋友关系\)
求\(n\)个人最后各自可以看见多少条说说
02.思路分析
思路1\((10pts)\):
对于\(n≤1000且m≤1000\) 思路显然:
输入\(m\)次操作
01.操作为\(2\)时:每次输入\(a,b\)并建边\([a,b]\)
02.操作为\(3\)时:删边\([a,b]\)
03.操作为\(1\)时:输入\(a\),将所有与\(a\)相连的点看见的说说数量\(ans[i]\)加1
最后输出\(ans[1\)~\(n]\)即可,复杂度\(O(mn)\)
思路2:\((100pts)\)
对于\(n≤30000且m≤30000\) 考虑降低时间复杂度
\(O(m)\)是难以被降低的,故考虑将\(O(mn)\)降为\(O(m)\)
那么就可以形成新的思路:
前置:
建立一个二维\(vector\)数组\(edge\),定义\(edge[Node1][i]\)表示\(Node1\)结点所连接的一个节点
那么我们可以用一些常用的数组操作来记录每个节点在\(edge[x]\)中的位置\(id\)
同时可以建立\(d\)数组来存储每个点已经发送的信息数量
显然我们可以\(O(1)\)时间完成对任意边的查询
则有:
01.操作\(2\)时:建边\([a,b]\),在\(edge[a]\)中push_back此时的\(d[a]\),存储\(id[a][b]\)
注意:\(vector\)内存储的时\(d[a]\)而非\(b\)
02.操作\(3\)时:删边\([a,b]\),将\(ans[b]\)存储为\(d[a]-edge[a]\)
03.操作\(1\)时:将\(d[a]++\)
注意: 操作完成后可能仍有边未删除,此时需要额外进行删边操作
#include<bits/stdc++.h>
#define int long long
const int MAXN=2e5+10;
using namespace std;
struct E
{
int u,v;
};
E arr[MAXN];
vector<int> edge[MAXN];
unordered_map<int,unordered_map<int,bool> > vis;
unordered_map<int,unordered_map<int,int> > id,id2;
int d[MAXN],ans[MAXN];
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
int n,m,cnt=0;
cin>>n>>m;
while(m--)
{
// cout<<"TTT"<<"\n";
char opt;
cin>>opt;
if(opt=='!')
{
int u;
cin>>u;
++d[u];
}
else if(opt=='+')//建边
{
int u,v;
cin>>u>>v;
// cout<<"2\n";
if(vis[u][v]==0)
{
//记录v在u中的位置
id[u][v]=edge[u].size();
id[v][u]=edge[v].size();
//建图
edge[u].push_back(d[u]);
edge[v].push_back(d[v]);
vis[u][v]=vis[v][u]=1;
int u2=min(u,v);
int v2=max(u,v);
// id2[u2][v2]=arr.size();
arr[++cnt]={u2,v2};
}
}
else//删边
{
int u,v;
cin>>u>>v;
if(vis[u][v]==1)
{
int sd=edge[u][id[u][v]];
ans[v]+=d[u]-sd;
sd=edge[v][id[v][u]];
ans[u]+=d[v]-sd;
vis[u][v]=vis[v][u]=0;
int u2=min(u,v);
int v2=max(u,v);
}
}
}
// cout<<"1\n";
for(int i=1;i<=cnt;++i)
{
int u=arr[i].u,v=arr[i].v;
if(vis[u][v])
{
int sd=edge[u][id[u][v]];
ans[v]+=d[u]-sd;
sd=edge[v][id[v][u]];
ans[u]+=d[v]-sd;
vis[u][v]=vis[v][u]=0;
}
}
for(int i=1;i<=n;++i)
cout<<ans[i]<<" ";
}

浙公网安备 33010602011771号