hihocoder的教程挺好理解,这里存代码。
1014 Trie树
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
#define ll long long
#define eps 10^(-6)
#define Q_CIN ios::sync_with_stdio(false);
#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )
#define FOR( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define CLR( a , x ) memset ( a , x , sizeof (a) );
#define RE freopen("1.in","r",stdin);
#define WE freopen("1.out","w",stdout);
#define MOD 10009
#define debug(x) cout<<#x<<":"<<(x)<<endl;
#define lson i<<1,l,m
#define rson i<<1|1,m+1,r
struct tree
{
tree *next[27];
int cnt;
tree(){
cnt=0;
CLR(next,NULL);
}
};
int n,m;
void add(tree *p,char *s1)
{
int i=0;
while(s1[i])
{
int k=s1[i]-'a';
if(!p->next[k])
p->next[k]=new tree();
p=p->next[k];
p->cnt++;
i++;
}
}
int query(tree *p,char *s1)
{
int i=0;
while(s1[i])
{
int k=s1[i]-'a';
if(!p->next[k]) return 0;
p=p->next[k];
i++;
}
return p->cnt;
}
int main()
{
// freopen("1.in","r",stdin);
int n,m;
char s1[30];
while(~scanf("%d%*c",&n))
{
tree *p=new tree();
for(int i=1;i<=n;i++)
{
scanf("%s",s1);
add(p,s1);
}
scanf("%d%*c",&m);
for(int i=1;i<=m;i++)
{
scanf("%s",s1);
printf("%d\n",query(p,s1));
}
}
return 0;
}
1015 KMP算法
#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;
#define ll long long
#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )
#define FOR( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define CLR( a , x ) memset ( a , x , sizeof (a) );
#define RE freopen("1.in","r",stdin);
#define WE freopen("1.out","w",stdout);
int Next[10005];
string s1,s2;
void getNext(string s1)
{
int i=-1,j=0;
int len=s1.length();
Next[0]=-1;
while(j<len)
{
if(i==-1||s1[i]==s1[j])
Next[++j]=++i;
else
i=Next[i];
}
}
int kmp(string s1,string s2) //s2里找s2,可重叠
{
int i=0,j=0;
int len1=s1.length();
int len2=s2.length();
int cnt=0;
for(int i=0;i<len1;i++)
{
while(j!=-1&&s1[i]!=s2[j])
j=Next[j];
if(j==-1||s1[i]==s2[j])
j++;
if(j==len2)
cnt++;
}
return cnt;
}
int main()
{
RE
int n;
cin>>n;
for(int i=0;i<n;i++)
{
cin>>s1>>s2;
getNext(s1);
cout<<kmp(s2,s1)<<endl;
}
}
1032 最长回文子串
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
#define ll long long
#define eps 10^(-6)
#define Q_CIN ios::sync_with_stdio(false);
#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )
#define FOR( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define CLR( a , x ) memset ( a , x , sizeof (a) );
#define RE freopen("1.in","r",stdin);
#define WE freopen("1.out","w",stdout);
#define MOD 10009
#define bug(x) cout<<#x<<":"<<(x)<<endl;
char s1[1000020],s2[2000100];
int len[1000000*2+8];
int init()
{
int len=strlen(s1),cnt=0;
REP(i,len){
s2[cnt++] = '#';
s2[cnt++] = s1[i];
}
s2[cnt++]='#';
s2[cnt]='\0';
return strlen(s2);
}
int Manacher()
{
int n=init();
int pos=0,mx=0,ans=1;
FOR(i,0,n-1){
if(mx>i){
len[i]=min(len[pos*2-i],mx-i);
}else{
len[i]=1;
}
while(i-len[i]>=0&&s2[i+len[i]]==s2[i-len[i]]) {
len[i]++;
}
if(len[i]+i>mx){
mx=len[i]+i;
pos=i;
}
ans=max(ans,len[i]);
}
return ans-1;
}
int main()
{
// RE
int t;
scanf("%d%*c",&t);
while(t--){
scanf("%s",s1);
printf("%d\n",Manacher());
}
return 0;
}
1050 树中的最长路
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <map>
#include <queue>
#include <set>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
#define ll long long
#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )
#define FOR( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define CLR( a , x ) memset ( a , x , sizeof (a) );
#define MOD 10009
#define bug(x) cout<<#x<<":"<<(x)<<endl;
vector<vector<int> > v;
int src,len;
// 任意一个点dfs求距离它最远的点,再从该点dfs求距离该点最远的点,则这次距离就是了
void dfs(int u,int depth,int father){ //father:父结点
if( depth > len){
len = depth;
src = u;
}
for (int i = 0; i < v[u].size(); ++i){
if(father != v[u][i]) //不能走回头路
dfs(v[u][i],depth+1,u);
}
}
int main(){
int n,a,b;
cin>>n;
v.resize(n+1); //!!!!!!!!!!!!!
for (int i = 0; i < n-1; ++i){
cin>>a>>b;
v[a].push_back(b);
v[b].push_back(a);
}
len = 0;
dfs(1,0,0);
len = 0;
dfs(src,0,0);
cout<<len<<endl;
return 0;
}
1093 最短路径·三:SPFA算法
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
#define ll long long
#define eps 10^(-6)
#define Q_CIN ios::sync_with_stdio(false);
#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )
#define FOR( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define CLR( a , x ) memset ( a , x , sizeof (a) );
#define RE freopen("1.in","r",stdin);
#define WE freopen("1.out","w",stdout);
#define MOD 10009
#define debug(x) cout<<#x<<":"<<(x)<<endl;
const int maxn=1e5+5;
const int maxm=1e6+5;
const int inf=1e3*maxm;
int inq[maxn],head[maxn],dis[maxn];
struct Edge
{
int v,w,next;
}edge[maxm*2];
int cnt;
void add_edge(int u,int v,int w)
{
edge[cnt].v=v;edge[cnt].w=w;edge[cnt].next=head[u];head[u]=cnt++;
}
void init(int n)
{
cnt=0;
CLR(head,-1);
CLR(inq,0);
FOR(i,1,n)
dis[i]=inf;
}
int spfa(int s,int t)
{
queue<int>q;
dis[s]=0;
inq[s]=1;
q.push(s);
while(!q.empty())
{
int u=q.front();q.pop();
inq[u]=0;
for(int i=head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].v;
int w=edge[i].w;
if(dis[v]>dis[u]+w)
{
dis[v]=dis[u]+w;
if(!inq[v])
{
inq[v]=1;
q.push(v);
}
}
}
}
return dis[t];
}
int main()
{
// RE
int n,m,s,t,a,b,c;
while(cin>>n>>m>>s>>t)
{
init(n);
REP(i,m)
{
cin>>a>>b>>c;
add_edge(a,b,c);
add_edge(b,a,c);
}
cout<<spfa(s,t)<<endl;
}
return 0;
}
1121 二分图一•二分图判定
给定的图可能不联通,所以一次搜索不行,如例子:
4 2
1 2
3 4
应为Correct
BFS
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
#define ll long long
#define INF 0x7FFFFFFF
#define INT_MIN -(1<<31)
#define eps 10^(-6)
#define Q_CIN ios::sync_with_stdio(false);
#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )
#define FOR( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define CLR( a , x ) memset ( a , x , sizeof (a) );
#define RE freopen("1.in","r",stdin);
#define WE freopen("1.out","w",stdout);
#define MOD 10009
#define debug(x) cout<<#x<<":"<<(x)<<endl;
const int maxn=10050;
vector<int>v[maxn];
int vis[maxn];
int n;
int match(int s)
{
queue<int>q;
q.push(s);
vis[s]=1;
int flag=0;
while(!q.empty())
{
int pre=q.front();
q.pop();
for(int i=0;i<v[pre].size();i++)
{
int x=v[pre][i];
if(vis[x]==-1)
{
vis[x]=!vis[pre];
q.push(x);
}else if(vis[x]==vis[pre])
return 0;
}
}
return 1;
}
int main()
{
// RE
int t,m,a,b;
cin>>t;
while(t--)
{
cin>>n>>m;
FOR(i,1,n)
v[i].clear();
CLR(vis,-1);
REP(i,m)
{
cin>>a>>b;
v[a].push_back(b);
v[b].push_back(a);
}
int ok=1;
FOR(i,1,n)
{
if(vis[i]==-1&&!match(i))
{
ok=0;
cout<<"Wrong"<<endl;
break;
}
}
if(ok)
cout<<"Correct"<<endl;
}
return 0;
}
DFS
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
#define ll long long
#define INF 0x7FFFFFFF
#define INT_MIN -(1<<31)
#define eps 10^(-6)
#define Q_CIN ios::sync_with_stdio(false);
#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )
#define FOR( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define CLR( a , x ) memset ( a , x , sizeof (a) );
#define RE freopen("1.in","r",stdin);
#define WE freopen("1.out","w",stdout);
#define MOD 10009
#define debug(x) cout<<#x<<":"<<(x)<<endl;
const int maxn=10050;
vector<int>v[maxn];
int vis[maxn];
int n;
int dfs(int s)
{
for(int i=0;i<v[s].size();i++)
{
int x=v[s][i];
if(vis[x]==-1)
{
vis[x]=!vis[s];
if(!dfs(x)) return 0;
}else if(vis[x]==vis[s])
return 0;
}
return 1;
}
int main()
{
RE
int t,m,a,b;
cin>>t;
while(t--)
{
cin>>n>>m;
FOR(i,1,n)
v[i].clear();
CLR(vis,-1);
REP(i,m)
{
cin>>a>>b;
v[a].push_back(b);
v[b].push_back(a);
}
int ok=1;
FOR(i,1,n)
{
if(vis[i]==-1)
{
vis[i]=1; //不能放进dfs里
if(!dfs(i))
{
ok=0;
cout<<"Wrong"<<endl;
break;
}
}
}
if(ok)
cout<<"Correct"<<endl;
}
return 0;
}
1122 二分图二 分图最大匹配之匈牙利算法
注意可能有多个联通块
#include <cstdio>
#include <cstring>
#include <queue>
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;
#define ll long long
#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )
#define FOR( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define CLR( a , x ) memset ( a , x , sizeof (a) );
#define RE freopen("1.in","r",stdin);
#define WE freopen("1.out","w",stdout);
const int maxn=1005;
const int maxm=5005;
int mat[maxn][maxn];
int arr[maxn][maxn];
int vis[maxn];
int match[maxn];
int team[maxn];
int n,m;
int cnt;
int can(int u)
{
for(int v=1;v<=n;v++)
{
if(mat[u][v]&&!vis[v])
{
vis[v]=1;
if(match[v]==-1||can(match[v]))
{
match[v]=u;match[v]=u;
return 1;
}
}
}
return 0;
}
void bfs(int u)
{
queue<int>q;
q.push(u);
team[u]=0;
while(!q.empty())
{
int x=q.front();q.pop();
for(int i=1;i<=n;i++)
{
if(arr[x][i]&&team[i]==-1)
{
team[i]=!team[x];
q.push(i);
}
}
}
}
int main()
{
// RE
int a,b;
while(cin>>n>>m)
{
cnt=0;
CLR(mat,0);
CLR(arr,0);
CLR(team,-1);
REP(i,m)
{
cin>>a>>b;
if(a!=b)
arr[a][b]=arr[b][a]=mat[a][b]=mat[b][a]=1;
}
for(int i=1;i<=n;i++)
{
if(team[i]==-1)
{
bfs(i);
}
}
CLR(match,-1);
FOR(i,1,n)
{
CLR(vis,0);
if(!team[i]&&can(i))
cnt++;
}
cout<<cnt<<endl;
}
return 0;
}
二分图三 二分图最小点覆盖和最大独立集
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
#define ll long long
#define eps 10^(-6)
#define Q_CIN ios::sync_with_stdio(false);
#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )
#define FOR( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define CLR( a , x ) memset ( a , x , sizeof (a) );
#define RE freopen("1.in","r",stdin);
#define WE freopen("1.out","w",stdout);
#define MOD 10009
#define debug(x) cout<<#x<<":"<<(x)<<endl;
#define lson i<<1,l,m
#define rson i<<1|1,m+1,r
int n,m;
int link[1005],vis[1005];
int mat[1005][1005];
int team[1005];
int can(int u)
{
for(int v=1;v<=n;v++)
{
if(mat[u][v]&&!vis[v])
{
vis[v]=1;
if(link[v]==-1||can(link[v]))
{
link[v]=u;
return 1;
}
}
}
return 0;
}
void bfs(int x)
{
queue<int>q;
q.push(x);
team[x]=0;
while(!q.empty())
{
int t=q.front();q.pop();
for(int v=1;v<=n;v++)
if(mat[t][v]&&team[v]==-1)
{
team[v]=!team[t];
q.push(v);
}
}
}
int main()
{
// freopen("1.in","r",stdin);
int a,b;
while(~scanf("%d%d",&n,&m))
{
memset(mat,0,sizeof(mat));
memset(link,-1,sizeof(link));
memset(team,-1,sizeof(team));
int cnt=0;
for(int i=1;i<=m;i++)
{
scanf("%d%d",&a,&b);
mat[a][b]=mat[b][a]=1;
}
for(int i=1;i<=n;i++)
if(team[i]==-1)
bfs(i);
for(int i=1;i<=n;i++)
{
memset(vis,0,sizeof(vis));
if(!team[i]&&can(i)) cnt++;
}
printf("%d\n%d\n",cnt,n-cnt);
}
return 0;
}
RMQ-ST算法
cin超时
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
#define ll long long
#define eps 10^(-6)
#define Q_CIN ios::sync_with_stdio(false);
#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )
#define FOR( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define CLR( a , x ) memset ( a , x , sizeof (a) );
#define RE freopen("1.in","r",stdin);
#define WE freopen("1.out","w",stdout);
#define MOD 10009
#define debug(x) cout<<#x<<":"<<(x)<<endl;
#define lson i<<1,l,m
#define rson i<<1|1,m+1,r
int arr[1000005],dp[1000005][20];
int n,m;
void init()
{
for(int i=1;i<=n;i++)
dp[i][0]=arr[i];
for(int j=1;(1<<j)<=n;j++)
{
for(int i=1;i+(1<<j)-1<=n;i++)
{
dp[i][j]=min(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);
}
}
}
int query(int l,int r)
{
int k=(int)log2(r-l+1.0);
return min(dp[l][k],dp[r-(1<<k)+1][k]);
}
int main()
{
// freopen("1.in","r",stdin);
int l,r;
scanf("%d",&n);
{
for(int i=1;i<=n;i++)
scanf("%d",&arr[i]);
scanf("%d",&m);
init();
for(int i=1;i<=m;i++)
{
scanf("%d%d",&l,&r);
printf("%d\n",query(l,r));
}
}
return 0;
}
1077 RMQ问题再临-线段树
单点更新,区间查询
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <map>
#include <queue>
#include <iostream>
#include <algorithm>
using namespace std;
#define ll long long
#define clr( a , x ) memset ( a , x , sizeof (a) );
#define RE freopen("1.in","r",stdin);
#define WE freopen("1.out","w",stdout);
#define MOD 10009
#define bug(x) cout<<#x<<":"<<(x)<<endl;
#define lson rt<<1,l,m
#define rson rt<<1|1,m+1,r
const int maxn = 1e6 + 5;
const int maxm = 1e6 + 5;
const int inf = 0x3f3f3f3f;
int val[maxn << 2];
void build(int rt, int l, int r) {
if (l == r) {
scanf("%d",&val[rt]);
} else {
int m = (l + r) >> 1;
build(lson);
build(rson);
val[rt] = min(val[rt << 1], val[rt << 1 | 1]);
}
}
void update(int rt, int l, int r, int pos, int num) {
if (l == r && r == pos) {
val[rt] = num;
} else {
int m = (l + r) >> 1;
if (pos <= m)
update(lson, pos, num);
else
update(rson, pos, num);
val[rt] = min(val[rt << 1], val[rt << 1 | 1]);
}
}
int query(int rt, int l, int r, int q1, int q2) {
if (q1 <= l && r <= q2) {
return val[rt];
}
int m = (l + r) >> 1, t1 = inf, t2 = inf;
if (q1 <= m)
t1 = query(lson, q1, q2);
if (q2 > m)
t2 = query(rson, q1, q2);
return min(t1, t2);
}
int main() {
int a, b, c, m, n;
scanf("%d",&n);
build(1, 1, n);
scanf("%d",&m);
while (m--) {
scanf("%d%d%d",&a,&b,&c);
if (a) {
update(1, 1, n, b, c);
} else {
printf("%d\n", query(1, 1, n, b, c));
}
}
return 0;
}
1078 线段树的区间修改线段树
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
#define ll long long
#define eps 10^(-6)
#define Q_CIN ios::sync_with_stdio(false);
#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )
#define FOR( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define CLR( a , x ) memset ( a , x , sizeof (a) );
#define RE freopen("1.in","r",stdin);
#define WE freopen("1.out","w",stdout);
#define MOD 10009
#define debug(x) cout<<#x<<":"<<(x)<<endl;
#define lson i<<1,l,m
#define rson i<<1|1,m+1,r
int sum[1000005<<2],add[1000005<<2];
int n,m;
void build(int i,int l,int r)
{
add[i]=0;
if(l==r)
{
scanf("%d",&sum[i]);
return;
}
int m=(l+r)/2;
build(lson);
build(rson);
sum[i]=sum[i<<1]+sum[i<<1|1];
}
void pushdown(int i,int m)
{
add[i<<1]=add[i<<1|1]=add[i];
sum[i<<1]=add[i]*(m-m/2);
sum[i<<1|1]=add[i]*(m/2);
add[i]=0;
}
void update(int i,int l,int r,int q1,int q2,int num)
{
if(q1<=l&&r<=q2)
{
add[i]=num;
sum[i]=(r-l+1)*num;
return;
}
int m=(l+r)/2;
if(add[i])
pushdown(i,r-l+1);
if(q1<=m)
update(lson,q1,q2,num);
if(q2>m)
update(rson,q1,q2,num);
sum[i]=sum[i<<1]+sum[i<<1|1];
}
int query(int i,int l,int r,int q1,int q2)
{
if(q1<=l&&r<=q2) return sum[i];
if(add[i])
pushdown(i,r-l+1);
int m=(l+r)/2;
int t1=0,t2=0;
if(q1<=m)
t1=query(lson,q1,q2);
if(q2>m)
t2=query(rson,q1,q2);
return t1+t2;
}
int main()
{
// freopen("1.in","r",stdin);
int l,r,c,num;
scanf("%d",&n);
{
build(1,1,n);
scanf("%d",&m);
for(int i=1;i<=m;i++)
{
scanf("%d",&c);
if(c==0)
{
scanf("%d%d",&l,&r);
printf("%d\n",query(1,1,n,l,r));
}else{
scanf("%d%d%d",&l,&r,&num);
update(1,1,n,l,r,num);
}
}
}
return 0;
}
1080 更为复杂的买卖房屋姿势
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
#define ll long long
#define eps 10^(-6)
#define Q_CIN ios::sync_with_stdio(false);
#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )
#define FOR( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define CLR( a , x ) memset ( a , x , sizeof (a) );
#define RE freopen("1.in","r",stdin);
#define WE freopen("1.out","w",stdout);
#define MOD 10009
#define debug(x) cout<<#x<<":"<<(x)<<endl;
#define lson i<<1,l,m
#define rson i<<1|1,m+1,r
int sum[100010<<2],add[100010<<2],eva[100010<<2];
int n,m;
void build(int i,int l,int r)
{
add[i]=0,eva[i]=0;
if(l==r)
{
scanf("%d",&sum[i]);
return;
}
int m=(l+r)/2;
build(lson);
build(rson);
sum[i]=sum[i<<1]+sum[i<<1|1];
}
void pushdown_eva(int i,int m)
{
eva[i<<1]=eva[i<<1|1]=eva[i];
sum[i<<1]=eva[i]*(m-m/2);
sum[i<<1|1]=eva[i]*(m/2);
eva[i]=0;
add[i<<1]=add[i<<1|1]=0; //赋值标记使得子区间的加值标记无效
}
void pushdown_add(int i,int m)
{
add[i<<1]+=add[i];
add[i<<1|1]+=add[i];
sum[i<<1]+=add[i]*(m-m/2);
sum[i<<1|1]+=add[i]*(m/2);
add[i]=0;
}
void update(int i,int l,int r,int q1,int q2,int num,int c)
{
if(q1<=l&&r<=q2)
{
if(c){
sum[i]=(r-l+1)*num;
eva[i]=num;
add[i]=0; //add标记被覆盖
}
else{
sum[i]+=(r-l+1)*num;
add[i]+=num;
}
return;
}
int m=(l+r)/2;
if(eva[i])
pushdown_eva(i,r-l+1);
if(add[i])
pushdown_add(i,r-l+1);
if(q1<=m)
update(lson,q1,q2,num,c);
if(q2>m)
update(rson,q1,q2,num,c);
sum[i]=sum[i<<1]+sum[i<<1|1];
}
int query(int i,int l,int r,int q1,int q2)
{
if(q1<=l&&r<=q2) return sum[i];
if(eva[i])
pushdown_eva(i,r-l+1);
if(add[i])
pushdown_add(i,r-l+1);
int m=(l+r)/2;
int t1=0,t2=0;
if(q1<=m)
t1=query(lson,q1,q2);
if(q2>m)
t2=query(rson,q1,q2);
return t1+t2;
}
int main()
{
// freopen("1.in","r",stdin);
int l,r,c,num;
scanf("%d%d",&n,&m);
{
n++;
build(1,1,n);
for(int i=1;i<=m;i++)
{
scanf("%d%d%d%d",&c,&l,&r,&num);
l++;r++;
update(1,1,n,l,r,num,c);
printf("%d\n",query(1,1,n,1,n));
}
}
return 0;
}
1044 状态压缩 一
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
#define ll long long
#define eps 10^(-6)
#define Q_CIN ios::sync_with_stdio(false);
#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )
#define FOR( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define CLR( a , x ) memset ( a , x , sizeof (a) );
#define RE freopen("1.in","r",stdin);
#define WE freopen("1.out","w",stdout);
#define MOD 10009
#define debug(x) cout<<#x<<":"<<(x)<<endl;
#define lson i<<1,l,m
#define rson i<<1|1,m+1,r
int dp[1005][1030];
int sum(int n)
{
int ans=0;
while(n)
{
ans+=n&1;
n>>=1;
}
return ans;
}
int main()
{
// freopen("1.in","r",stdin);
int n,m,q;
int a[1005];
while(~scanf("%d%d%d",&n,&m,&q))
{
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
// memset(dp,0,sizeof(dp));
for(int i=1;i<=n;i++)
for(int j=0;j<(1<<m)-1;j++)
{
if(sum(j)<q)
dp[i][j]=max(dp[i-1][(j/2)+(1<<(m-2))],dp[i-1][j/2]);
else if(sum(j)>q)
dp[i][j]=0;
else
dp[i][j]=dp[i-1][j/2];
if((j>>(m-2))&1) dp[i][j]+=a[i];
}
int ans=0;
for(int j=0;j<(1<<m)-1;j++)
ans=max(dp[n][j],ans);
printf("%d\n",ans);
}
return 0;
}
1089 最短路径 二:Floyd算法
#include <cstdio>
#include <string.h>
#include <vector>
#include <algorithm>
#include <iostream>
#define rep( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define clr( a , x ) memset ( a , x , sizeof (a) );
using namespace std;
const int maxn = 105;
const int inf = 0x3f3f3f3f;
int n,m;
int dp[maxn][maxn];
void floyd(){
rep(k,1,n){
rep(i,1,n){
rep(j,1,n){
dp[i][j] = min(dp[i][j],dp[i][k]+dp[k][j]);
}
}
}
}
int main(){
int a,b,c;
while(cin>>n>>m){
clr(dp,inf);
rep(i,1,n)
dp[i][i]=0;
rep(i,1,m){
cin>>a>>b>>c;
dp[a][b] = dp[b][a] = min(dp[a][b],c);
}
floyd();
rep(i,1,n){
rep(j,1,n-1){
cout<<dp[i][j]<<" ";
}
cout<<dp[i][n]<<endl;
}
}
return 0;
}
1097 最小生成树一 Prim算法
#include <iostream>
#include <algorithm>
#include <math.h>
#include <string.h>
#include <cmath>
using namespace std;
const int maxn = 1e3+50;
const int maxM = 25300*502;
int dis[maxn];
int vis[maxn];
int n;
int mp[maxn][maxn];
int prim(int src){
for (int i = 1; i <= n; ++i){
dis[i] = mp[src][i];
}
memset(vis,0,sizeof(vis));
dis[src] = 0;
vis[src] = 1;
int ret = 0;
for (int i = 1; i < n; ++i)
{
int minDis = 9999999,minIdx;
for (int j = 1; j <= n; ++j)
{
if(!vis[j] && dis[j] < minDis){
minDis = dis[j];
minIdx = j;
}
}
vis[minIdx] = 1;
ret += minDis;
for (int j = 1; j <= n; ++j)
{
// if(!vis[j] && dis[minIdx] + mp[minIdx][j] < dis[j]){
// dis[j] = dis[minIdx] + mp[minIdx][j];
// }
if(!vis[j] && mp[minIdx][j] < dis[j]){
dis[j] = mp[minIdx][j];
}
}
}
return ret;
}
int main() {
while (cin >> n ) {
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= n; ++j) {
cin >> mp[i][j];
}
}
memset(dis, 0, sizeof(dis));
int ret = prim(1);
cout << ret << endl;
}
return 0;
}
1142 三分·三分求极值
#include <cstdio>
#include <cmath>
#include <iostream>
#include <algorithm>
using namespace std;
double a,b,c,x,y;
double val(double X){
return sqrt((X-x)*(X-x)+(a*X*X+b*X+c-y)*(a*X*X+b*X+c-y));
}
double solve(double l,double r){
double eps = 1e-5;
while(l+eps<r){
double lmid = l + (r-l)/3,rmid = r - (r-l)/3;
if(val(lmid) < val(rmid)){
r = rmid;
}else{
l = lmid;
}
}
return val(l);
}
int main(){
cin>>a>>b>>c>>x>>y;
printf("%.3f\n", solve(-200.0,200.0));
return 0;
}
1183 连通性一·割边与割点
Tarjan算法简化版,注意是无向边 和 边上点的大小关系
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;
#define ll long long
#define clr( a , x ) memset ( a , x , sizeof (a) );
#define RE freopen("1.in","r",stdin);
#define WE freopen("1.out","w",stdout);
#define SpeedUp std::cout.sync_with_stdio(false);
#define debug(x) cout << "Line " << __LINE__ << ": " << #x << " = " << x << endl;
const int maxn = 20005;
const int maxm = 200052; //~无向边
const int inf = 0x3f3f3f3f;
int head[maxn];
int dfn[maxn], low[maxn];
int cnt;
bool vis[maxn];
int next[maxn];
int father[maxn];
int eCnt;
struct Edge
{
int v, next;
} edge[maxm];
void add(int u, int v) {
edge[eCnt].v = v, edge[eCnt].next = head[u], head[u] = eCnt++;
edge[eCnt].v = u, edge[eCnt].next = head[v], head[v] = eCnt++;
}
struct B
{
int u,v;
bool operator < (const struct B bb) const{
if(u==bb.u)
return v<bb.v;
return u<bb.u;
}
}bridge[maxm]; //存答案的边
int bCnt;
bool node[maxn];
void dfs(int u) {
dfn[u] = low[u] = cnt++;
vis[u] = true;
int child = 0;
for (int i = head[u]; i != -1; i = edge[i].next) {
int v = edge[i].v;
if (!vis[v]) {
child++;
father[v] = u;
dfs(v);
low[u] = min(low[u], low[v]);
if (father[u] == -1 && child >= 2) {
node[u] = true;
}
if (father[u] != -1 && low[v] >= dfn[u]) {
node[u] = true;
}
if (low[v] > dfn[u]) {
bridge[bCnt].u = min(u,v);
bridge[bCnt++].v = max(u,v);
}
}else if (v != father[u]) {
low[u] = min(low[u], dfn[v]);
}
}
}
int main() {
// RE
int n, m;
int a, b;
while (cin >> n >> m) {
eCnt = 0;
clr(head, -1);
clr(vis, false);
clr(father,-1);
clr(node,false);
clr(dfn,0);
clr(low,0);
cnt = 0;
bCnt = 0;
for (int i = 0; i < m; ++i) {
cin >> a >> b;
add(a, b);
}
dfs(1);
int first = true;
int no = 1;
for (int i = 1; i <= n; ++i){
if(node[i]){
if(first){
first = false;
cout<<i;
}
else{
cout<<" "<<i;
}
no = 0;
}
}
if(no){
cout<<"Null";
}
cout<<endl;
sort(bridge,bridge+bCnt);
for (int i = 0; i < bCnt; ++i){
cout<<bridge[i].u<<" "<<bridge[i].v<<endl;
}
// for (int i = 1; i <= n; ++i){
// cout<<"dfn="<<dfn[i]<<" low="<<low[i]<<endl;
// }
}
return 0;
}
1066 无间道之并查集
https://hihocoder.com/problemset/solution/1271732
#include <iostream>
#include <algorithm>
#include <math.h>
#include <string.h>
#include <cmath>
#include <map>
using namespace std;
const int maxn = 100005;
const int maxM = 25300*502;
int root[maxn*2];
int n;
int findRoot(int cur){
if(cur == root[cur]){
return cur;
}
return root[cur] = findRoot(root[cur] );
}
int merge(int x,int y){
int rootX = findRoot(x);
int rootY = findRoot(y);
if(rootX != rootY){
root[rootX] = rootY;
}
}
int main() {
int op;
string str1,str2;
map<string,int>mp;
while (cin >> n ) {
for (int i = 0; i <= n; i++) {
root[i] = i;
}
mp.clear();
int cnt = 0;
for (int i = 0; i < n; i++) {
cin >> op >> str1 >> str2;
int idx1 ,idx2 ;
idx1 = mp[str1];idx2 = mp[str2];
if( mp[str1] == 0){
idx1 = mp[str1] = ++cnt;
}
if( mp[str2] == 0){
idx2 = mp[str2] = ++cnt;
}
if(op==1){
// cout<< idx1 << " " << idx2 << " === "<< endl;
if( findRoot(idx1) == findRoot(idx2) ){
cout<<"yes"<<endl;
}else{
cout<<"no"<<endl;
}
}else{
merge(idx1,idx2);
// for (int i = 0; i < cnt; i++) {
// cout<<word[i]<< " " << i << " "<<findRoot(i) << endl;
// }
}
}
}
return 0;
}
1038 01背包
https://hihocoder.com/problemset/solution/1270589
#include <iostream>
#include <algorithm>
#include <math.h>
#include <string.h>
#include <cmath>
using namespace std;
const int maxN = 555;
const int maxM = 25300*502;
int main() {
int n, m;
int cost[maxN], val[maxN];
int dp[maxM];
while (cin >> n >> m) {
for (int i = 0; i < n; ++i) {
cin >> cost[i] >> val[i];
}
memset(dp, 0, sizeof(dp));
int ans = 0;
for (int i = 0; i < n; ++i) {
for (int j = m; j >= cost[i]; --j) {
dp[j] = max(dp[j], dp[j - cost[i]] + val[i]);
}
}
cout << dp[m] << endl;
}
return 0;
}
1081 最短路径·一
https://hihocoder.com/problemset/solution/1271836 注意路是双向的,跟prim就差几行代码
#include <iostream>
#include <algorithm>
#include <math.h>
#include <string.h>
#include <cmath>
using namespace std;
const int maxn = 1e3+50;
const int maxM = 25300*502;
const int inf = 0x3f3f3f3f;
int dis[maxn];
int vis[maxn];
int n;
int mp[maxn][maxn];
int dijkstra(int src,int dst){
for (int i = 1; i <= n; ++i){
dis[i] = mp[src][i];
}
memset(vis,0,sizeof(vis));
dis[src] = 0; vis[src] = 1;
for (int i = 1; i < n; ++i)
{
int minDis = inf,minIdx = 0;
for (int v = 1; v <= n; ++v)
{
if(!vis[v] && dis[v] < minDis){
minDis = dis[v];
minIdx = v;
}
}
vis[minIdx] = 1;
for (int v = 1; v <= n; ++v)
{
if(!vis[v] && dis[minIdx] + mp[minIdx][v] < dis[v]){
dis[v] = dis[minIdx] + mp[minIdx][v];
}
}
}
return dis[dst];
}
int main() {
int s,t,a,b,val,m;
while (cin >> n >> m >> s >> t) {
memset(mp, inf, sizeof(mp));
for (int i = 0; i < m; ++i) {
cin >> a >> b >> val;
mp[b][a] = mp[a][b] = min(mp[a][b],val);
}
int ret = dijkstra(s,t);
cout << ret << endl;
}
return 0;
}