目录
A (1). Sum 详细点击:sum //整除分块
B (2). Sort
C (3). String //字符串dp
D (4). Factor //素数筛变式
E (5). Tree //树形dp
F (6). Geometry //几何
G (7). Graph //二分答案
H (8). Line //贪心
I (9). And / Or //位运算
J (10). Mov //模拟
#include
using namespace std;
typedef long long ll;
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
ll T,x,y;
void solve() {
ll res=0;
cin>>x>>y;
ll i=min((ll)sqrt(x),y);
while(i*i+i+1>x)
i--;
res=(1+i)*i/2;
for(ll l=i+1,r; l<=y,l+1<=x; l=r+1) {
r=x/(x/(l+1))-1;
r=min(r,y);
if(l>r)
break;
res+=x/(l+1)*(r-l+1);
}
cout<>T;
while(T--)
solve();
return 0;
}
使用stable_sort强行卡过,优化可了解:sort 学长Ashy深情讲解
#include
using namespace std;
struct node {
long long x,y;
} d[100001];
long long e[100001];
long long n,q,t,u,v;
bool cmp(node a,node b) {
return a.x==b.x?a.y>n>>q;
for(long long i=1; i<=n; i++)
cin>>d[i].x,d[i].y=i;
/*
for(int i=1; i<=n; i++)
cout<>t;
if(t==1) {
cin>>u>>v;
d[e[u]].x=v;
stable_sort(d+1,d+1+n,cmp);
for(int i=1; i<=n; ++i)
e[d[i].y]=i;
} else {
cin>>u;
cout<
在这提一下stable_sort和sort的区别,单纯从性能来讲sort性能更好,因为stable_sort要维护数据的稳定性,丧失了一部分性能,但在大部分数据顺序不变的情况下,stable_sort要比sort快很多
字符串dp,即区间dp
#include
using namespace std;
//最长回文串子序列
int n;
string s;
int dp[2100][2100];
//字符串s在区间[i, j]范围内的最长回文子序列的长度
//dp[i][j] = dp[i+1][j-1] + 2;
//dp[i][j] = (dp[i+1][j] > dp[i][j-1]) ? dp[i+1][j] : dp[i][j-1];
int main() {
cin>>n>>s;
for (int i=0;idp[i][j-1])?dp[i+1][j]:dp[i][j-1];
}
}
}
cout<
用埃式筛暴力筛出来的,时间复杂度为O(nlogn)
#include
using namespace std;
const int maxn=1e6+1;
int n,a,ans;
bool vis[maxn];
int main() {
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
cin>>n;
for(int i=1; i<=n; i++)
cin>>a,vis[a]=true;
for(int i=1; i<=maxn; i++)
for(int j=i; j<=maxn; j+=i)
if(vis[j]) {
ans++;
break;
}
cout<
树形DP模板题
#include
using namespace std;
typedef long long ll;
const ll N=1e6+10;
ll a[N],u,v;
ll f[N],tot;
struct Edge {
int to,next;
} edges[N];
int head[N],edge_len,n;
void Add(int from,int to) {
edges[++edge_len].next=head[from];
edges[edge_len].to=to;
head[from]=edge_len;
}
void Dfs(ll e,ll fa) {
bool flag=0;
f[e]+=a[e];
for(int i=head[e]; ~i; i=edges[i].next) {
if(edges[i].to!=fa) {
flag=1;
Dfs(edges[i].to,e);
f[e]+=f[edges[i].to];
}
}
}
int main() {
memset(head,-1,sizeof head);
cin>>n;
for(int i=1; i<=n; i++)
cin>>a[i],tot+=a[i];
for(int i=1; i>u>>v;
Add(u,v);
Add(v,u);
}
Dfs(1,0);
ll mx=0;
for(int i=2; i<=n; i++)
mx=max(mx,abs(f[i]-(tot-f[i])));
cout<
把梯形补成三角形
补出来的三角形与等腰三角形是相似三角形,通过三角形相似我们可以得出来
通过以上三式解方程就可以了。
#include
using namespace std;
//梯形补成三角形
//按照比求三角形高与H圆心到三角形顶点的距离d+H
//H=b/(a-b)*h
//c=r*h*2/(a-b)
//d+H=sqrt(c*c+r*r)
double r,a,b,c,h,H,d;
int main() {
cin>>r>>a>>b>>h;
if(2*r
二分答案,judge函数用于判断给定的时间t是否满足从起点x到终点y的路径存在。
#include
using namespace std;
const int N=2e6+10;
typedef long long ll;
int n,m,x,y;
int head[N],edge_len;
struct edge {
int next,to;
ll w;
} edges[N];
int u[N],v[N],w[N];
bool vis[N];
void Add(int from,int to,ll w) {
edges[++edge_len].next=head[from];
edges[edge_len].to=to;
edges[edge_len].w=w;
head[from]=edge_len;
}
void Dfs(int e) {
if(vis[e])
return;
vis[e]=true;
for(int i=head[e]; ~i; i=edges[i].next) {
if(!vis[edges[i].to])
Dfs(edges[i].to);
}
}
bool judge(int t) {
for(int i=0;i<=n;++i)
head[i]=-1,vis[i]=false;
edge_len=0;
for(int i=0; it)
continue;
Add(v[i],u[i],w[i]);
}
Dfs(x);
return vis[y];
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
cin>>n>>m>>x>>y;
for(int i=0; i>u[i]>>v[i]>>w[i];
int l=0,r=1e9,mid;
while(l>1;
if(judge(mid))
r=mid;
else
l=mid+1;
}
cout<
贪心的思想,按边的右端点排序,以第一个右端点向右扩大k,找到第一个超出此范围的左端点,并将其右端点作为新的lc
#include
using namespace std;
typedef long long ll;
ll n,k,cnt;
struct node {
ll l,r;
} d[1000001];
bool cmp(node a,node b) {
return (a.r==b.r)?a.l>n>>k;
for (int i=0; i>d[i].l>>d[i].r;
sort(d,d+n,cmp);
ll lr=d[0].r+k;
for (int i=1; i
我们知道按位或是不进位加法, 恒成立。
因此只要把每个数进行按位与操作就可以得到最大值
#include
using namespace std;
int n,a[100001],ans;
int main() {
cin>>n;
for(int i=1; i<=n; i++) {
cin>>a[i];
ans|=a[i];
}
cout<
模拟题,没啥好说的
#include
using namespace std;
int n;
string s,t;
int a[1000001];
int main() {
cin>>n;
while(n--) {
cin>>s>>t;
//cout<'9') {
int y=0;
for(int j=i+2; j