维护一个单调序列,要用set。常用的set操作如下:
#include<bits/stdc++.h>
using namespace std;
multiset<int> S;
int main(void)
{
int n;cin>>n;
for(int i=0;i<n;i++){
int op,num;
cin>>op>>num;
if(op==5)
S.insert(num);
else if(op==3){
auto it=S.lower_bound(num);
if(it!=S.begin()) cout<<*(--it)<<endl;
else cout<<"-2147483647"<<endl;
}else if(op==4){
auto it=S.upper_bound(num);
if(it!=S.end()) cout<<*it<<endl;
else cout<<"2147483647"<<endl;
}else if(op==2){
auto it=S.begin();
int cnt=num-1;
while(cnt--) it++;
cout<<*it<<endl;
}
else{
auto it=S.lower_bound(num);
int rank=1;
while(it!=S.begin()){
it--;
rank++;
}
cout<<rank<<endl;
}
}
}
状态压缩DP,经典哈密顿路径
#include<bits/stdc++.h>
using namespace std;
vector<pair<double,double> > V;
double dp[1<<16][21];
double dist[21][21];
double fun(int a,int b)
{
int x=V[a].first,y=V[a].second;
int u=V[b].first,v=V[b].second;
return sqrt((x-u)*(x-u)+(y-v)*(y-v));
}
int main(void)
{
memset(dp,0x7f,sizeof(dp));
int n;cin>>n;
V.push_back({0,0});
for(int i=0;i<n;i++){
double x,y;cin>>x>>y;
V.push_back({x,y});
}
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
if(i!=j)
dist[i][j]=fun(i,j);
n++;
dp[1][0]=0;
for(int S=1;S<(1<<n);S++)
for(int j=0;j<n;j++)
if((S>>j)&1)
for(int k=0;k<n;k++)
if((S^(1<<j)) >> k & 1)
dp[S][j]=min(dp[S^(1<<j)][k]+dist[k][j],dp[S][j]);
double Min=0x7f7f7f7f;
for(int j=1;j<=n;j++)
Min=min(Min,dp[(1<<n)-1][j]);
printf("%.2lf",Min);
}
BFS
#include<bits/stdc++.h>
using namespace std;
string a,b;
vector<pair<string,string> > V;
map<string,bool> flag;
int Min=0;
//void dfs(string x,string y,int step)
//{
// if(step>10) return ;
// if(step>=Min) return ;
// if(x==y){
// Min=min(Min,step);
// return ;
// }
//
//
// for(int i=0;i<V.size();i++){
// auto it=V[i];
// string u=it.first,v=it.second;
// string ans;
// int idx=0;
// while((idx=x.find(u,idx)) != -1){
// if(idx==-1) break;
// ans=x;
// ans.replace(idx,u.length(),v);
// if(flag[ans]) continue;
// flag[ans]=true;
// dfs(ans,y,step+1);
// flag[ans]=false;
// idx+=u.length();
// }
// }
//}
int bfs()
{
queue<string> Q;
Q.push(a);
flag[a]=true;
int Min=0;
while(Q.size()){
int cnt=Q.size();
Min++;
if(Min>10) return Min;
while(cnt--){
string x=Q.front();
// cout<<x<<endl;
Q.pop();
if(x==b) return Min;
for(int i=0;i<V.size();i++){
auto it=V[i];
string u=it.first,v=it.second;
string ans;
int idx=0;
while((idx=x.find(u,idx)) != -1){
if(idx==-1) break;
// cout<<ans<<" "<<x<<" "<<i<<" "<<idx<<endl;
ans=x;
ans.replace(idx,u.length(),v);
idx+=u.length();
if(flag[ans]) continue;
flag[ans]=true;
Q.push(ans);
}
}
}
}
return 11;
}
int main(void)
{
cin>>a>>b;
string u,v;
while(cin>>u>>v)
V.push_back({u,v});
int Min=bfs();
if(Min>10) cout<<"NO ANSWER!";
else cout<<Min-1;
}
二分图+二分排序
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int idx=0;
int h[N],ne[6*N],e[6*N],w[6*N];
vector<int> V;
bool flag[N];
int color[N];
bool ok;
int n,m;
void add(int u,int v,int d)
{
ne[idx]=h[u];
e[idx]=v;
w[idx]=d;
h[u]=idx++;
}
void dfs(int dist,int t)
{
if(!ok)
return ;
for(int i=h[t];i!=-1;i=ne[i]){
int v=e[i],d=w[i];
if(d>dist){
if(!flag[v]){
if(color[t]==1)
color[v]=2;
else
color[v]=1;
flag[v]=true;
dfs(dist,v);
}
else{
if(color[v]==color[t]){
ok=false;
}
}
}
}
}
void check(int mid)
{
memset(color,0,sizeof(color));
memset(flag,false,sizeof(flag));
ok=true;
int dist=V[mid];
for(int i=1;i<=n;i++){
if(ok&&!flag[i]){
color[i]=1;
dfs(dist,i);
}
}
}
int main(void)
{
memset(h,-1,sizeof(h));
cin>>n>>m;
for(int i=0;i<m;i++){
int a,b,c;
cin>>a>>b>>c;
add(a,b,c);
add(b,a,c);
V.push_back(c);
}
sort(V.begin(),V.end());
if(n==2)
cout<<0;
else{
int l=0,r=V.size()-1;
while(l<r){
int mid=l+r>>1;
check(mid);
if(ok)
r=mid;
else
l=mid+1;
}
cout<<V[l];
}
}
并查集,解决逻辑矛盾问题
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int fa[N];
int n;
struct Node{
Node(){
}
Node(int u,int v,int d){
x=u;
y=v;
e=d;
}
int x,y,e;
};
struct Node a[N];
vector<int> book;
void init(int n)
{
for(int i=0;i<=n;i++)
fa[i]=i;
}
int Find(int x)
{
if(x==fa[x])
return fa[x];
return fa[x]=Find(fa[x]);
}
bool cmp(struct Node A,struct Node B)
{
return A.e>B.e;
}
int main(void)
{
int T;cin>>T;
while(T--){
int cnt=0;
bool ok=false;
cin>>n;
for(int i=0;i<n;i++){
int u,v,d;
cin>>u>>v>>d;
a[i]={u,v,d};
book.push_back(u);
book.push_back(v);
}
sort(book.begin(),book.end());
book.erase(unique(book.begin(),book.end()),book.end());
init(book.size());
for(int i=0;i<n;i++){
a[i].x=lower_bound(book.begin(),book.end(),a[i].x)-book.begin();
a[i].y=lower_bound(book.begin(),book.end(),a[i].y)-book.begin();
}
sort(a,a+n,cmp);
for(int i=0;i<n;i++){
int u=Find(a[i].x),v=Find(a[i].y);
if(a[i].e){
if(u!=v)
fa[u]=v;
}
else if(u==v){
printf("NO\n");
ok=true;
break;
}
}
if(!ok) cout<<"YES"<<endl;
book.clear();
}
}
与第一题类似。
#include<bits/stdc++.h>
using namespace std;
const int inf=0x7f7f7f7f;
set<int> S;
int main(void)
{
S.insert(inf);S.insert(-inf);
int n;cin>>n;
int num;cin>>num;
S.insert(num);
int Sum=num;
for(int i=1;i<n;i++){
cin>>num;
auto it=S.lower_bound(num);
int p=*it;
int q=*(--it);
// cout<<"---- "<<p<<endl;
Sum+=min(abs(num-p),abs(num-q));
S.insert(num);
}
cout<<Sum<<endl;
}