L2-3清点代码库
赛中只拿了21分,中间一个点t了,应该先吧所有的数据读完,再把数量也存到vector里,然后进行排序,这样可以减少map的访问次数。
#include<bits/stdc++.h>
using namespace std;
map<vector<int>,int> M;
int n,m,x;
vector<int> cnt;
vector<pair<vector<int>,int>> ans;
bool cmp(pair<vector<int>,int> a,pair<vector<int>,int> b){
if(a.second==b.second){
return a.first<b.first;
}else{
return a.second>b.second;
}
}
int main(){
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++){
cnt.clear();
for(int j=0;j<m;j++){
scanf("%d",&x);
cnt.push_back(x);
}
M[cnt]++;
}
for(map<vector<int>,int>::iterator i=M.begin();i!=M.end();i++){
ans.push_back({i->first,i->second});
}
sort(ans.begin(),ans.end(),cmp);//排序
printf("%d\n",ans.size());
for(int i=0;i<ans.size();i++){
printf("%d",ans[i].second);
for(int j=0;j<m;j++){
printf(" %d",ans[i].first[j]);
}
printf("\n");
}
}
L3-1森森旅行
赛中直接暴力19分, 解法是跑正向反向的单源最短路,然后用线段树或分块维护最小值(看了y总的multiset,发现自己根本没学过这个数据结构)
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int n,m,q,u,v,c,d;
struct Edge{
vector<int> to,c;
}edges[100005];
struct Edge2{
vector<int> to,d;
}edges2[100005];
int a[100005];
ll d1[100005],d2[100005];
bool vis[100005];
struct st{
ll dis,id;
friend bool operator < (st a,st b){
return a.dis>b.dis;
}
};
priority_queue<st,vector<st>>pq;
void dij(){
memset(d1,-1,sizeof(d1));
memset(vis,0,sizeof(vis));
pq.push({0,1});
while(!pq.empty()){
st cnt=pq.top();
pq.pop();
if(vis[cnt.id])
continue;
vis[cnt.id]=1;
d1[cnt.id]=cnt.dis;
for(int i=0;i<edges[cnt.id].to.size();i++){
pq.push({cnt.dis+edges[cnt.id].c[i],edges[cnt.id].to[i]});
}
}
return;
}
void dij2(){
memset(d2,-1,sizeof(d2));
memset(vis,0,sizeof(vis));
pq.push({0,n});
while(!pq.empty()){
st cnt=pq.top();
pq.pop();
if(vis[cnt.id])
continue;
vis[cnt.id]=1;
d2[cnt.id]=cnt.dis;
for(int i=0;i<edges2[cnt.id].to.size();i++){
pq.push({cnt.dis+edges2[cnt.id].d[i],edges2[cnt.id].to[i]});
}
}
return;
}
void add(int u,int v,int c,int d){
edges[u].to.push_back(v);
edges[u].c.push_back(c);
edges2[v].to.push_back(u);
edges2[v].d.push_back(d);
return;
}
ll ans[100005],ans2[1005];
int main(){
scanf("%d %d %d",&n,&m,&q);
for(int i=1;i<=m;i++){
scanf("%d %d %d %d",&u,&v,&c,&d);
add(u,v,c,d);
}
dij();
dij2();
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
int sn=sqrt(n);
for(int i=0;i<=n/sn;i++){
ans2[i]=2e18;
}
for(int i=1;i<=n;i++){
if(d1[i]==-1||d2[i]==-1)
continue;
ans[i]=(d1[i]+d2[i]/a[i]+(d2[i]%a[i]?1:0));
ans2[i/sn]=min(ans[i],ans2[i/sn]);
//cout<<i<<' '<<ans[i]<<endl;
}
while(q--){
int x,y;
scanf("%d %d",&x,&y);
a[x]=y;
if(d1[x]!=-1&&d2[x]!=-1)
ans[x]=d1[x]+d2[x]/a[x]+(d2[x]%a[x]?1:0);
int w=x/sn,z=min(n,(x/sn+1)*sn-1);
ans2[w]=2e18;
for(int i=x/sn*sn;i<=z;i++){
if(d1[i]!=-1&&d2[i]!=-1)
ans2[w]=min(ans2[w],ans[i]);
}
ll res=2e18;
for(int i=0;i<=n/sn;i++){
res=min(res,ans2[i]);
}
printf("%lld\n",res);
}
}
multiset\
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int n,m,q,u,v,c,d;
struct Edge{
vector<int> to,c;
}edges[100005];
struct Edge2{
vector<int> to,d;
}edges2[100005];
int a[100005];
ll d1[100005],d2[100005];
bool vis[100005];
struct st{
ll dis,id;
friend bool operator < (st a,st b){
return a.dis>b.dis;
}
};
priority_queue<st,vector<st>>pq;
void dij(){
memset(d1,-1,sizeof(d1));
memset(vis,0,sizeof(vis));
pq.push({0,1});
while(!pq.empty()){
st cnt=pq.top();
pq.pop();
if(vis[cnt.id])
continue;
vis[cnt.id]=1;
d1[cnt.id]=cnt.dis;
for(int i=0;i<edges[cnt.id].to.size();i++){
pq.push({cnt.dis+edges[cnt.id].c[i],edges[cnt.id].to[i]});
}
}
return;
}
void dij2(){
memset(d2,-1,sizeof(d2));
memset(vis,0,sizeof(vis));
pq.push({0,n});
while(!pq.empty()){
st cnt=pq.top();
pq.pop();
if(vis[cnt.id])
continue;
vis[cnt.id]=1;
d2[cnt.id]=cnt.dis;
for(int i=0;i<edges2[cnt.id].to.size();i++){
pq.push({cnt.dis+edges2[cnt.id].d[i],edges2[cnt.id].to[i]});
}
}
return;
}
void add(int u,int v,int c,int d){
edges[u].to.push_back(v);
edges[u].c.push_back(c);
edges2[v].to.push_back(u);
edges2[v].d.push_back(d);
return;
}
int main(){
scanf("%d %d %d",&n,&m,&q);
for(int i=1;i<=m;i++){
scanf("%d %d %d %d",&u,&v,&c,&d);
add(u,v,c,d);
}
dij();
dij2();
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
multiset<ll> S;
for(int i=1;i<=n;i++){
if(d1[i]!=-1&&d2[i]!=-1){
S.insert((d1[i]+(d2[i]+a[i]-1)/a[i]));
}
}
while(q--){
int x,y;
scanf("%d %d",&x,&y);
if(d1[x]!=-1&&d2[x]!=-1){
S.erase(S.find(d1[x]+(d2[x]+a[x]-1)/a[x]));
a[x]=y;
S.insert(d1[x]+(d2[x]+a[x]-1)/a[x]);
}
printf("%lld\n",*S.begin());
}
}