A:最长上升子串
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <cmath>
using namespace std;
#define rep(i,a,n) for (int i=a;i<=n;i++)
#define per(i,n,a) for (int i=n;i>=a;i--)
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define SZ(x) ((int)(x).size())
#define fi first
#define se second
typedef vector<int> VI;
typedef long long ll;
typedef pair<int,int> PII;
const ll mod=1000000007;
ll powmod(ll a,ll b) {ll res=1;a%=mod;for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
#define Fast_IO ios_base::sync_with_stdio(0);cin.tie(0)
int n;
int a[100100];
int main()
{
cin>>n;
int res = 1;
int t = 1;
scanf("%d", &a[1]);
rep(i, 2, n){
scanf("%d", &a[i]);
if(a[i] >= a[i-1]) t++;
else t = 1;
res = max(t, res);
}
cout<<res<<endl;
return 0;
}
B: 排序后二分。或者排序后尺取。 因为排序后就是单调的了
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <cmath>
using namespace std;
#define rep(i,a,n) for (int i=a;i<=n;i++)
#define per(i,n,a) for (int i=n;i>=a;i--)
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define SZ(x) ((int)(x).size())
#define fi first
#define se second
typedef vector<int> VI;
typedef long long ll;
typedef pair<int,int> PII;
const ll mod=1000000007;
ll powmod(ll a,ll b) {ll res=1;a%=mod;for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
#define Fast_IO ios_base::sync_with_stdio(0);cin.tie(0)
int n, d;
PII a[100100];
int minn[100100];
int maxn[100100];
ll sum[100100];
const int INF = 0x3f3f3f3f;
int main()
{
cin>>n>>d;
rep(i, 1, n){
int x,y;
scanf("%d %d", &x, &y);
a[i].fi = x; a[i].se = y;
}
sort(a+1, a+n+1);
ll res = -1;
for(int i=1; i<=n; i++){
sum[i] = sum[i-1] + a[i].se;
}
for(int i=1; i<=n; i++){
int tmp = lower_bound(a+i, a+n+1, mp(d+a[i].fi, -1)) - a - 1;
res = max(sum[tmp] - sum[i-1], res);
}
cout<<res<<endl;
return 0;
}
C:水dfs 求有多少条能到达子节点的路径且中间连续的猫不超过k个。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <cmath>
using namespace std;
#define rep(i,a,n) for (int i=a;i<=n;i++)
#define per(i,n,a) for (int i=n;i>=a;i--)
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define SZ(x) ((int)(x).size())
#define fi first
#define se second
typedef vector<int> VI;
typedef long long ll;
typedef pair<int,int> PII;
const ll mod=1000000007;
ll powmod(ll a,ll b) {ll res=1;a%=mod;for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
#define Fast_IO ios_base::sync_with_stdio(0);cin.tie(0)
int n,m;
vector<int> v[100100];
int a[100100];
int ans = 0;
void dfs(int u, int pre, int d){
bool is = true;
int size = v[u].size();
for(int i=0; i<size; i++){
int tmp = d;
int to = v[u][i];
if(to == pre) continue;
is = false;
if(a[to] == 0) tmp = 0;
else if(tmp + 1 > m) continue;
else tmp++;
dfs(to, u, tmp);
}
if(is) ans++;
}
int main()
{
cin>>n>>m;
rep(i, 1, n) scanf("%d", &a[i]);
rep(i, 1, n-1){
int x,y;
scanf("%d %d", &x, &y);
v[x].pb(y);
v[y].pb(x);
}
dfs(1, -1, a[1]);
cout<<ans<<endl;
return 0;
}
D:状压dp 和tsp问题基本一样
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <cmath>
using namespace std;
#define rep(i,a,n) for (int i=a;i<=n;i++)
#define per(i,n,a) for (int i=n;i>=a;i--)
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define SZ(x) ((int)(x).size())
#define fi first
#define se second
typedef vector<int> VI;
typedef long long ll;
typedef pair<int,int> PII;
const ll mod=1000000007;
ll powmod(ll a,ll b) {ll res=1;a%=mod;for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
#define Fast_IO ios_base::sync_with_stdio(0);cin.tie(0)
int n,m,k;
int a[100];
ll dp[300000][20];
ll res = 0;
struct node{
int to,w,next;
}edge[4000];
int tot;
int head[400];
void init(){
tot = 0; memset(head, -1, sizeof(head));
}
void add_edge(int u, int v, int w){
edge[tot].to = v;
edge[tot].w = w;
edge[tot].next = head[u];
head[u] = tot++;
}
bool check(int s){
int tmp = 0;
while(s){
if(s&1) tmp++;
s>>=1;
}
return tmp==m;
}
bool g[20][20] = {false};
int main(){
cin>>n>>m>>k;
init();
rep(i, 0, n-1)scanf("%d", a+i);
rep(i, 1, k){
int x,y,z;
scanf("%d %d %d", &x, &y, &z);
x--, y--;
add_edge(x, y, z);
g[x][y] = true;
}
rep(i, 0, n-1)
rep(j, 0, n-1){
if(i == j) continue;
if(g[i][j] == false)
add_edge(i, j, 0);
}
int sum = (1<<n);
for(int i=0; i<n;i++)
dp[1<<i][i] = a[i];
for(int i=1; i<sum; i++){
for(int j=0; j<n; j++){
if((i&(1<<j)) == 0) continue;
for(int k=head[j]; ~k; k=edge[k].next){
int v = edge[k].to;
int w = edge[k].w;
if(i&(1<<v))continue;
dp[i|(1<<v)][v] = max(dp[i][j] + w + a[v], dp[i|(1<<v)][v]);
}
}
}
for(int i=1; i<sum; i++){
if(check(i))
for(int j=0; j<n; j++){
if(i&(1<<j))
res = max(res, dp[i][j]);
}
}
cout<<res<<endl;
return 0;
}
E:线段树+hash。 为了不被卡 写了双hash,传说中的多项式hash大法
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <cmath>
using namespace std;
#define rep(i,a,n) for (int i=a;i<=n;i++)
#define per(i,n,a) for (int i=n;i>=a;i--)
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define SZ(x) ((int)(x).size())
#define fi first
#define se second
typedef vector<int> VI;
typedef long long ll;
typedef pair<int,int> PII;
typedef unsigned long long ull;
const ll mod=1000000007;
ll powmod(ll a,ll b) {ll res=1;a%=mod;for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
#define Fast_IO ios_base::sync_with_stdio(0);cin.tie(0)
int n,m,k;
const int mod2 = 1000000009;
const int MAXN = 100100;
const int seed = 13;
ll p[MAXN+10];
ll p2[MAXN +10];
ll sum[MAXN+10];
ll sum2[MAXN+10];
char a[MAXN+10];
void init(){
p[0] = 1;
sum[0] = 1;
p2[0] = 1;
sum2[0] = 1;
for(int i=1; i<MAXN; i++){
p[i] = p[i-1]*seed%mod;
sum[i] = (sum[i-1]+p[i]) % mod;
p2[i] = p2[i-1]*seed%mod2;
sum2[i] = (sum2[i-1]+p2[i])%mod2;
}
}
struct node{
int l, r;
int len;
long long val;
long long val2;
int lazy;
}tree[MAXN*4];
void push_up(int i){
tree[i].val = (tree[i<<1].val*p[tree[i<<1|1].len]%mod + tree[i<<1|1].val)%mod;
tree[i].val2 = (tree[i<<1].val2*p2[tree[i<<1|1].len]%mod2 + tree[i<<1|1].val2)%mod2;
}
void push_down(int i){
if(tree[i].lazy != -1){
tree[i<<1].val = sum[tree[i<<1].len-1] * tree[i].lazy % mod;
tree[i<<1|1].val = sum[tree[i<<1|1].len-1] * tree[i].lazy % mod;
tree[i<<1].val2 = sum2[tree[i<<1].len-1] * tree[i].lazy % mod2;
tree[i<<1|1].val2 = sum2[tree[i<<1|1].len-1] * tree[i].lazy % mod2;
tree[i<<1].lazy = tree[i].lazy;
tree[i<<1|1].lazy = tree[i].lazy;
tree[i].lazy = -1;
}
}
void build(int i, int l, int r){
tree[i].l = l;
tree[i].r = r;
tree[i].len = r - l + 1;
tree[i].lazy = -1;
if(l == r){
tree[i].val = a[l] - '0';
tree[i].val2 = a[l] - '0';
return;
}
int mid = (l+r)>>1;
build(i<<1, l, mid);
build(i<<1|1, mid+1, r);
push_up(i);
}
void update(int i, int l, int r, int val){
if(tree[i].l == l&&tree[i].r == r){
tree[i].val = val*sum[tree[i].len-1]%mod;
tree[i].val2 = val*sum2[tree[i].len-1]%mod2;
tree[i].lazy = val;
return;
}
push_down(i);
int mid = (tree[i].l + tree[i].r)>>1;
if(l > mid) update(i<<1|1, l, r, val);
else if(r <= mid) update(i<<1, l, r, val);
else{
update(i<<1, l, mid, val);
update(i<<1|1, mid+1, r, val);
}
push_up(i);
}
pair<long long, long long> query(int i, int l, int r){
if(tree[i].l == l && tree[i].r == r){
return mp(tree[i].val, tree[i].val2);
}
push_down(i);
int mid = (tree[i].l + tree[i].r)>>1;
if(l > mid) return query(i<<1|1, l, r);
else if(r <= mid) return query(i<<1, l, r);
else{
pair<long long, long long> a =query(i<<1, l, mid);
pair<long long, long long> b =query(i<<1|1, mid+1, r);
long long t1 = (a.fi*p[r - (mid+1) + 1]%mod + b.fi)%mod;
long long t2 = (a.se*p2[r - (mid+1) + 1]%mod2 + b.se)%mod2;
return mp(t1, t2);
}
}
int main()
{
init();
cin>>n>>m>>k;
scanf("%s", a+1);
int q = m+k;
build(1, 1, n);
while(q--){
int cmd, x, y, z;
scanf("%d %d %d %d", &cmd, &x, &y, &z);
if(cmd == 2) {
if(y-x+1 == z) {puts("YES"); continue;};
pair<long long, long long> a = query(1, x, y-z);
pair<long long, long long> b = query(1, x+z, y);
if(a.fi == b.fi && a.se == b.se) printf("YES\n");
else printf("NO\n");
}
else
update(1, x, y, z);
}
return 0;
}