常见算法模板整理

动态规划

[模板]01背包

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+7;

struct node
{
    int val,vol;
}item[maxn];

int n,m;
int dp[maxn];

void _01backpack()
{
    for(int i=1;i<=n;i++)
    {
        for(int j=m;j>=item[i].vol;j--)
        {
            dp[j]=max(dp[j],dp[j-item[i].vol]+item[i].val);
        }
    }
}

[模板]LDS和LIS

#include <bits/stdc++.h>
using namespace std;
const int maxn=1e6+7;

int a[maxn];
int d[maxn];

int LIS_LDS(int n)
{
    int len;
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    d[len=1]=a[1];
    for(int i=2;i<=n;i++)
    {
        if(a[i]>d[len]) d[++len]=a[i];
        else *lower_bound(d+1,d+1+n,a[i]) = a[i];//
    }
    return len;
}

/* 不同类型的最长XX子序列除了改变第四行的运算符号之外,第五行的代码也要相应变化:

最长上升子序列:查找大于等于 lower_bound(...)
最长下降子序列:查找小于等于 upper_bound(...,greater<int>())
最长不下降子序列LIS:查找大于 lower_bound(...)
最长不上升子序列LDS:查找小于 upper_bound(...,greater<int>()) */

[模板]LCS最长公共子序列

#include<bits/stdc++.h>
#define endl "\n"
#define pb push_back
#define ALL(x) x.begin(),x.end()
using namespace std;
typedef long long ll;
typedef pair<ll,ll> pll;
typedef pair<int,int> pii;
const int inf=INT_MAX;
const int mod=1e9+7;
const int maxn=1e3+7;
const int Maxn=1e5+7;

int n;
int dp[maxn][maxn];

int f[Maxn];
map<int,int> mp;

void LCS_1()//O(n^2)LCS朴素做法,只能到10^3的数据范围
{
	cin>>n;
	vector<int> a(n+1), b(n+1);
	for(int i=1; i<=n; i++)	cin>>a[i];
	for(int i=1; i<=n; i++)	cin>>b[i];
	int len1=n,len2=n;
	for(int i=1; i<=len1; i++)
    {
        for(int j=1; j<=len2; j++)
        {
			dp[i][j] = max(dp[i-1][j],dp[i][j-1]);
			if(a[i] == b[j])
			{
				dp[i][j] = max(dp[i][j],dp[i-1][j-1]+1);
			}
        }
	}
	cout<<dp[len1][len2]<<endl;//输出最长公共子序列的长度
}

void LCS_2()//O(nlogn)	大于10^5的数据范围
{
	cin>>n;
	vector<int> a(n+1),b(n+1);
	for(int i=1;i<=n;i++)
	{
		cin >> a[i];
		mp[a[i]]=i;
	}
	for(int i=1;i<=n;i++)
	{
		cin >> b[i];
		f[i]=0x7fffffff;
	}
	int len=0;
	f[0]=0;
	for (int i=1; i<=n; i++)
	{
		int l=0, r=len, mid;
		if(mp[b[i]] > f[len])	f[++len]=mp[b[i]];
		else 
		{
			while (l < r)
			{	
				mid = (l+r)/2;
				if(f[mid] > mp[b[i]])	r = mid;
				else l = mid+1; 
			}
			f[l] = min(mp[b[i]], f[l]);
     	}
    }
    cout<<len<<endl;//输出最长公共子序列的长度;
}

基本算法

[模板]高精度四则运算

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

string Addition(string a,string b)//高精度加法
{
    int sa[1000]={0};
    int sb[1000]={0};
    int sc[1000]={0};
    for(int i=1;i<=a.size();i++)    sa[i]=a[a.size()-i]-'0';
    for(int i=1;i<=b.size();i++)    sb[i]=b[b.size()-i]-'0';
    int Max=max(a.size(),b.size());
    for(int i=1;i<=Max;i++)
    {
        sc[i]=sc[i]+sa[i]+sb[i];
        sc[i+1]=sc[i]/10;
        sc[i]=sc[i]%10;
    }
    if(sc[Max+1]!=0)    Max++;
    string s;
    for(int i=Max;i>=1;i--)
    {
        s+=sc[i]+'0';
    }
    return s;
}
string Subtraction(string a,string b)//高精度减法
{
    bool flag=false;
    if((a.size()==b.size()&&a<b)||a.size()<b.size())
    {
        return "-"+Subtraction(b,a);
    }
    int na[10500]={0};
    int nb[10500]={0};
    int ans[10500]={0};
    for(int i=a.size()-1;i>=0;i--)  na[a.size()-i]=a[i]-'0';
    for(int i=b.size()-1;i>=0;i--)  nb[b.size()-i]=b[i]-'0';
    int max1=max(a.size(),b.size());
    for(int i=1;i<=max1;i++)
    {
        if(na[i]<nb[i])
        {
            na[i+1]--;
            na[i]+=10;
        }
        ans[i]=na[i]-nb[i];
    }
    string s;
    while(ans[max1]==0)
        max1--;
    if(max1<1)
    {
        return "0";
    }
    for(int i=max1;i>=1;i--)
        s+=(ans[i]+'0');
    return s;
}

string Multiplication(string a,string b)//高精度乘法
{
    int sa[1000];
    int sb[1000];
    int sc[1000]={0};
    for(int i=0;i<a.size();i++)    sa[i]=a[a.size()-1-i]-'0';
    for(int i=0;i<b.size();i++)    sb[i]=b[b.size()-1-i]-'0';
    int _max=a.size()+b.size();
    for(int i=0;i<a.size();i++)
    {
        for(int j=0;j<b.size();j++)
        {
            sc[i+j]+=sa[i]*sb[j];
            sc[i+j+1]+=(sc[i+j])/10;
            sc[i+j]=sc[i+j]%10;
        }
    }
    while(sc[_max-1]==0&&_max>1)    _max--;
    string s;
    for(int i=_max-1;i>=0;i--)
    {
        s+=sc[i]+'0';
    }
    return s;
}

[模板]前缀和

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e3+7;

class One_Dimension//一维
{
    int a[maxn];
    int pre[maxn];
    int n;

    void Create()
    {
        cin>>n;
        for(int i=1;i<=n;i++)
        {
            cin>>a[i];
            pre[i]=pre[i-1]+a[i];
        }
    }

    int Sum_interval(int l,int r)//l左端点,r右端点
    {
        return pre[r]-pre[l-1];
    }
};

class Double_Dimension//二维
{
    int a[maxn][maxn];
    int pre[maxn][maxn];
    int n;
    
    void Create()
    {
        cin>>n;
        for (int i=1; i<=n; i++)
        {
            for (int j=1; j<=n; j++)
            {
                cin >> a[i][j];
                pre[i][j]=pre[i-1][j]+pre[i][j-1]-pre[i-1][j-1]+a[i][j];
            }
        }
    }

    int Sum_interval(int i,int j,int k,int l)//从 左上(k,l) 到 右下(i,j) 的和
    {
        return pre[i][j]-pre[k-1][j]-pre[i][l-1]+pre[k-1][l-1];
    }
};

数据结构

[模板]单调队列

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> pll;
const int maxn=1e5+7;

void Priority_queue(vector<int>& v)
{
    priority_queue<pll,vector<pll>,less<pll> > q1;
    priority_queue<pll,vector<pll>,greater<pll> > q2;
    vector<ll> ans1,ans2;//ans1为最大值,ans2为最小值
    int n,k;
    cin>>n>>k;//n个数,每次扫描k个数据
    for(int i=1;i<=n;i++)
        cin>>v[i];
    for(int i=1;i<=n;i++)
    {
        pll temp={v[i],i};
        q1.push(temp);
        q2.push(temp);
        if(i>=k)//判断范围
        {
            while(q1.top().second<=i-k)
                q1.pop();
            ans1.push_back(q1.top().first);
            while(q2.top().second<=i-k)
                q2.pop();
            ans2.push_back(q2.top().first);
        }
    }
    for(auto i:ans2)
        cout<<i<<" ";
    cout<<endl;
    for(auto i:ans1)
        cout<<i<<" ";
}

[模板]单调栈

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+7;

void priority_stack(vector<int>& v)
{
    v.push_back(INT_MAX);
	stack<int> st;
	int sum = 0;
	for (int i=0; i<v.size(); i++)
	{
		if (st.empty() || v[st.top()] > v[i])
			st.push(i);
		else
		{
			while (!st.empty() && v[st.top()] <= v[i])
			{
				int top = st.top();
				st.pop();
			}
			st.push(i);
		}
	}
}

[模板]ST表

#include<bits/stdc++.h>
#define endl "\n"
using namespace std;
typedef long long ll;

const int maxn=2e5+7;
const int pows=21;
int st_max[maxn][pows+1];
int st_min[maxn][pows+1];

int query_max(int l,int r)//查询最大
{
    int len=log2(r-l+1);
    return max(st_max[l][len],st_max[r-(1<<len)+1][len]);
}

int query_min(int l,int r)//查询最小
{
    int len=log2(r-l+1);
    return min(st_min[l][len],st_min[r-(1<<len)+1][len]);
}

void ST()
{
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++)//对于i,从i开始的2^0个数的最值就是其本身
    {
        int temp;
        cin>>temp;
        st_max[i][0]=temp;
        st_min[i][0]=temp;
    }
    for(int j=1; j<=pows; j++)//对st表的处理
    {
        for(int i=1; i+(1<<j)<=n+1; i++)
        {
            st_max[i][j]=max(st_max[i][j-1],st_max[i+(1<<(j-1))][j-1]);
            st_min[i][j]=min(st_min[i][j-1],st_min[i+(1<<(j-1))][j-1]);
        }
    }
}

[模板]树状数组

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+5;

int tree[maxn];
int c[maxn];//c是原数组的差分数组
int n;

int lowbit(int x)//最低位的1
{
    return x&(-x);
}

void add_point(int x,int k)//单点修改,树状数组单点修改,对tree[x]操作
{
    for(int i=x;i<=n;i+=lowbit(i))
        tree[i]+=k;
}

ll ask_interval_1_X(int x)//区间查询,查询[1,x]的区间和
{
    ll sum=0;
    for(int i=x; i; i-=lowbit(i))
    {
        sum += tree[i];
    }
    return sum;
}

ll ans_interval_L_R(int L,int R)//区间查询,查询[L,R]的区间和,方法:[L,R]=[1,R]-[L-1,R];
{
    ll ans=0;
    for(int i = R; i>0; i -= lowbit(i))
    {
        ans += tree[i];
    }
    for(int i = L-1; i>0; i -= lowbit(i))
    {
        ans -= tree[i];
    }
    return ans;
}

void update(int pos,int k)//区间修改,对区间[L,R]+k,那么我们只需要更新差分数组update(L,k),update(R+1,-k)
{
    for(int i=pos; i<=n; i += lowbit(i))
    {
        c[i] += k;
    }
}
//[L,R]+k = update(L,k) , update(R+1,-k);

ll ask(int pos)//单点查询,返回[pos,1]的总和
{
    ll ans=0;
    for(int i=pos; i; i -= lowbit(i)) ans += c[i];
    return ans;
}

[模板]线段树

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=5e5+10;

struct node
{
    int l,r,lz,mlz;
    ll sum;
}tree[maxn];

int input[maxn];
ll ans;

inline void push_down(int i)
{
    if(tree[i].lz!=0)
    {
        tree[i*2].lz+=tree[i].lz;//左右儿子分别加上父亲的lz
        tree[i*2+1].lz+=tree[i].lz;
        int mid=tree[i].l + tree[i].r >> 1;
        tree[i*2].sum += tree[i].lz * (mid - tree[i*2].l + 1);//左右分别求和加起来
        tree[i*2+1].sum += tree[i].lz * (tree[i*2+1].r - mid);
        tree[i].lz = 0;//父亲lz归零
    }
    return;
}

inline void build(int i, int L, int R)//建树
{
    tree[i].l=L;
    tree[i].r=R;
    if(L==R)//如果这个节点是叶子结点
    {
        tree[i].sum=input[L];
        return;
    }
    int mid=(L+R)>>1;
    build(i*2,L,mid);
    build(i*2+1,mid+1,R);
    tree[i].sum=tree[i*2].sum+tree[i*2+1].sum;
}

inline int search(int i,int L,int R)//区间查询,返回[L,R]的和,i是指从哪个节点开始查询,一般是根节点
{
    if( tree[i].l>=L && tree[i].r<=R)  return tree[i].sum;//如果这个区间被完全包括在目标区间里面,直接返回这个区间的值
    if( tree[i].l>R || tree[i].r<L) return 0;//如果这个区间和目标区间毫不相干,返回0
    push_down(i);
    int s=0;
    if(tree[i*2].r>=L)   s+=search(i*2,L,R);//如果这个区间的左儿子和目标区间又交集,那么搜索左儿子
    if(tree[i*2+1].l<=R)    s+=search(i*2+1,L,R);//如果这个区间的右儿子和目标区间又交集,那么搜索右儿子
    return s;
}

inline void add_point(int i,int dis,int k)//单点修改,dis就是你要加的那个点
{
    if(tree[i].l == tree[i].r)//如果是叶子节点,那么说明找到了
    {
        tree[i].sum += k;
        return;
    }
    if(dis <= tree[i*2].r)    add_point(i*2, dis, k);//在哪往哪跑
    else    add_point(i*2+1, dis, k);
    tree[i].sum = tree[i*2].sum + tree[i*2+1].sum;//返回更新
    return;
}

inline void add_interval(int i,int L,int R,int k)//区间修改
{
    if(tree[i].l >= L && tree[i].r <= R)
    {
        tree[i].sum += k*(tree[i].r - tree[i].l + 1);
        tree[i].lz+=k;
        return;
    }
    push_down(i);
    if(tree[i*2].r >= L)
        add_interval(i*2, L, R, k);
    if(tree[i*2+1].l <= R)
        add_interval(i*2+1, L, R, k);
    tree[i].sum = tree[i*2].sum + tree[i*2+1].sum;
}

inline void ask_point(int p, int x)//单点查询
{
    ans += tree[p].sum;
    if(tree[p].l == tree[p].r)    return;
    int mid = tree[p].l + tree[p].r >>1;
    if(x <= mid)    ask_point(p << 1, x);
    else ask_point(p << 1 | 1, x);
}

数学

[模板]除法逆元

#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll mod; //宏定义一个mod
 
//快速幂优化
ll quick_pow(ll a,ll b)
{
    ll ans=1;
    while(b){
        if(b&1) ans=(ans*a)%mod;
        b>>=1;
        a=(a*a)%mod;
    }
    return ans;
}
 
//逆元函数 公式为 (a/b)%mod=(a*b^(mod-2))%mod
ll inv(ll a,ll b)
{
    return (a*quick_pow(b,mod-2))%mod;
}
 
/***
注意事项:逆元函数的使用,a必须能整除b,并且mod为质数
**/
 
int main()
{
    ll a,b;
    while(cin>>a>>b>>mod){
        cout<<inv(a,b)<<endl;
    }
    return 0;
}
 
 

[模板]分解质因数

#include <bits/stdc++.h> 
using namespace std;

int Fenjie(int n)//返回n的质因数个数
{
    int res=0;
    for(int i=2;i<=n/i;i++)
    {
        if(n%i==0)
        {
            res++;
            while(n%i==0)   n/=i;
        }
    }
    if(n>1) res++;//没有分解干净,原数也是一个质数
    return res;
}

[模板]快速幂

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e9+7;

ll FastPow(int a,int n)
{
    ll base=a;
    ll res=1;
    while(n)
    {
        if(n&1) res=(res*base)%mod;
        base=(base*base)%mod;
        n>>=1;
    }
    return res;
}

[模板]组合数取模

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll p = 1e9+7;
//组合数取模模板(p较大时,如p=1e9+7) 
ll Pow(ll a,ll b)
{
	ll ans=1;
	while(b){
		if(b&1) ans=(ans*a)%p;
		a=(a*a)%p;
		b>>=1;
	}
	return ans;
}
 
ll C(ll n,ll m)
{
	if(m==0) return 1;
	if(m>n-m) m=n-m;
	ll up=1,down=1;
	for(int i=1;i<=m;i++){
		up=(up*(n-i+1))%p;
		down=(down*i)%p;
	}
	return up*Pow(down,p-2)%p;
}
 
/***
目的:输出C(n,m)%mod的值
时间复杂度:O(m)
**/
 
int main()
{
    ll m,n;
    while(scanf("%lld%lld",&n,&m)!=EOF){
    	printf("%lld\n",C(n,m));
	}
    return 0;
}

STL

[STL]nth_element

#include<bits/stdc++.h>
using namespace std;
bool cmp(int a, int b){
    return a > b;
}

//C++的STL库中的nth_element()方法,默认是求区间第k小的(划重点)。
//nth_element(a,a+n-k,a+n),将下标为n-k,也就是第n-k+1个数放在正确的位置,求的是第k大的数a[n-k]。
int main()
{
	int a[9] = {4,7,6,9,1,8,2,3,5};
	int b[9] = {4,7,6,9,1,8,2,3,5};
	int c[9] = {4,7,6,9,1,8,2,3,5};
	nth_element(a,a+2,a+9);
	//将下标为2,也就是第3个数放在正确的位置
	//也就是求的是第3小
	cout <<"第3小是:"<< a[2] << endl;
	for(int i = 0; i < 9; i++)
    cout << a[i] << " "; puts("");//注意下标是从0開始计数的
	//那么求第3大,就是求第9-3+1小,即第7小
	//也就是将下标为6的第7个数,放在正确的位置
	nth_element(b,b+6,b+9);
	cout <<"第3大是:"<< b[6] << endl;
	for(int i = 0; i < 9; i++)
	cout << b[i] << " "; puts("");//注意下标是从0開始计数的
	nth_element(c,c+2,c+9,cmp);//第一种方法
	//nth_element(c,c+2,c+9,greater<int>()); //第二种方法
	cout <<"第3大是:"<< c[2] << endl;
	for(int i = 0; i < 9; i++)
	cout << c[i] << " "; //注意下标是从0開始计数的
}

图论

[模板]链式前向星

#include<bits/stdc++.h>
using namespace std;
const int maxn=2e6+7;

struct node//边:终点 to,权值 w,下一天边 next,起点放在 head[] 中
{
    int to, next, w;
}edge[maxn];

int head[maxn];//head[u] 指向结点 u 的第一个边的储存位置
int cnt;//记录 edge[] 的末尾位置。新加入的边放在末尾

void init()//初始化
{
    for (int i = 0; i < maxn; i++)
    {
        head[i] = -1;//-1:不存在从结点 i 出发的边
        edge[i].next = -1;//-1:结束,没有下一个边
    }
    cnt = 0;
}

void add_edge(int u,int v,int w)
{
    edge[cnt].to = v;
    edge[cnt].w = w;
    edge[cnt].next = head[u];//指向结点 u 上一次存的边的位置
    head[u] = cnt++;//更新节点 u 最新边的存放位置:就是 edge 的末尾
}

[模板]邻接表

#include<bits/stdc++.h>
#define endl "\n";
using namespace std;
typedef long long ll;
const int maxn=1e5+7;

struct edge//定义边
{
    int from, to, w;
    edge(int a, int b, int c) {from=a; to=b; w=c;} 
};

vector<edge> e[maxn];
int n;

void initial()//初始化
{
    for(int i=1; i<=n; i++)
        e[i].clear();
}

void add_edge(int a,int b,int c)//存边
{
    e[a].push_back(edge(a,b,c));
}

void ask_edge(int u)//检索结点u的所有邻居
{
    for(int i=0; i<e[u].size(); i++)
    {
        return;//...
    }
}

[模板]拓扑排序

#include<bits/stdc++.h>
using namespace std;
const int maxn=2e6+7;

class BFS_LinJieBiao//一:基于BFS的拓扑排序,用邻接表存储
{
    int n,m;//n是有几个结点,m是有几条边
    int in[maxn];//记录入度
    vector<int> edge[maxn];//边
    vector<int> ans;//排序结果
    queue<int> q;//队列


    void init()
    {
        for(int i=1; i<=m; i++)
        {
            int from,to;
            cin>>from>>to;
            edge[from].push_back(to);
            in[to]++;
        }
        for(int i=1;i<=n;i++)
        {
            if(in[i]==0)
                q.push(i);
        }
    }

    bool topsort()
    {
        while(!q.empty())
        {
            int t = q.front();
            ans.push_back(t);
            q.pop();
            for (int i=0; i<edge[t].size(); i++)
            {
                in[edge[t][i]]--;
                if (in[edge[t][i]] == 0)
                    q.push(edge[t][i]);
            }
        }
        if (ans.size() == n)
        {
            for(int i=0; i<n; i++)
                cout<<ans[i];
            return true;
        }
        else
        {
            return false;
        }
    }
};

class BFS_LianShiQianXiangXing//一:基于BFS的拓扑排序,用链式前向星存储,用优先队列实现了输出最小字典序的排序
{
    struct node
    {
        int to,next;
    }edge[maxn];
    int n,m,cnt;
    int head[maxn];
    int in[maxn];//入度
    vector<int> ans;
    priority_queue<int, vector<int>, greater<int> > q;

    void init()
    {
        for(int i=0;i<maxn;i++)
        {
            head[i]=-1;
            in[i]=0;
            cnt=0;
        }
    }

    void add(int u,int v)
    {
        edge[cnt] = node{v, head[u]};
        head[u] = cnt++;
        in[v]++;
    }

    bool topsort()
    {
        for (int i=1; i<=n; i++)
            if (in[i] == 0)
                q.push(i);
        while (!q.empty())
        {
            int u = q.top();
            q.pop();
            ans.push_back(u);
            for (int i=head[u]; i!=-1; i=edge[i].next)
            {
               if (--in[edge[i].to==0])
                    q.push(edge[i].to);
            }
        }
        if(ans.size()==n)
        {
            for (int i=0; i<n; i++)
            {
                cout<<ans[i];
            }
        }
        else
        {
            return false;
        }
    }
};

[模板]LCA最近公共祖先

#include<bits/stdc++.h>
#define endl "\n"
using namespace std;

const int maxn=5e5+7;
const int pows=20;

struct node
{
    int t,nex;
}e[maxn*2];

int head[maxn],tot;
int fa[maxn][pows+1];//记录节点i的2^j级父节点
int depth[maxn];
int lg[maxn];
int n,m,s;

inline void compute_log2()//预先算出log_2(i)+1的值,用的时候直接调用就可以了,常数优化
{
    for(int i=1; i<=n; i++) 
	    lg[i] = log2(i) + 1;/* lg[i-1] + (1 << lg[i-1] == i); */
}

inline void add(int x,int y)//加入树
{
    e[++tot].t = y;
    e[tot].nex = head[x];
    head[x] = tot;
}

inline void dfs(int now, int fath)//now表示起始节点,fath表示其父节点
{
    fa[now][0] = fath; // 初始化:第 2^0 = 1 个祖先就是它的父亲节点,dep 也比父亲节点多 1。
    depth[now] = depth[fath] + 1;
    for(int i=1; i<=lg[depth[now]]; i++)
    {
        fa[now][i] = fa[fa[now][i-1]][i-1];//now的2^i祖先等于now的2^(i-1)祖先的2^(i-1)祖先
    }
    for(int i=head[now]; i; i=e[i].nex)
    {
        if(e[i].t != fath) dfs(e[i].t, now);
    }

}

inline int LCA(int x,int y)//计算 x 和 y 的LCA
{
    if(depth[x] < depth[y])//假设x的深度 >= y的深度
        swap(x, y);
    while(depth[x] > depth[y])
        x = fa[x][lg[depth[x]-depth[y]]-1];
    if(x == y)//x是y的祖先
        return x;
    for(int k=lg[depth[x]]-1; k>=0; k--)//向上跳
    {
        if(fa[x][k] != fa[y][k])//因为我们要跳到它们LCA的下面一层,所以它们肯定不相等,如果不相等就跳过去。
        {
            x = fa[x][k];
            y = fa[y][k];
        }
    }
    return fa[x][0];
}

杂项

[模板]蔡勒公式

#include <iostream>
using namespace std;
int main() {
    int year, month, day;
    cout << "请用数字输出年、月、日,并使用空格隔开:" << endl;
    while (cin >> year >> month >> day) {
        if (month < 3) {
            year -= 1;
            month += 12;
        }
        char week[7][10] = {"Sunday",   "Monday", "Tuesday", "Wednesday",
                            "Thursday", "Friday", "Saturday"};
        int c = int(year / 100), y = year - 100 * c;
        int w = int(c / 4) - 2 * c + y + int(y / 4) + (26 * (month + 1) / 10) +
                day - 1;
        w = (w % 7 + 7) % 7;
        cout << week[w] << endl;
    }
    return 0;
}

[模板]基姆拉尔森计算公式

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=1e9+7;

int Date(int y,int m,int d)
{
    if(m==1||m==2){//一二月换算
        m+=12;
        y--;
    }
    int week = (d + 2*m +3*(m+1)/5 + y + y/4 - y/100 + y/400 + 1)%7;
    return week;//其中1~7表示周一到周日
}

int main()
{
    //0是周日
    cout<<Date(2024,1,13);
}
   

优化

[优化]区间伸缩

#include<bits/stdc++.h>
#define endl "\n"
using namespace std;
typedef long long ll;
const int inf=INT_MAX;
const int mod=1e9+7;
const int maxn=1e6+7;
const int bmax=2e3+7;
int v[maxn];
int b[bmax];

//洛谷P1638 逛画展

void solve()
{
    int n,m;
    cin>>n>>m;
    pair<int,int> p;
    for(int i=1;i<=n;i++)
    {
        cin>>v[i];
    }
    int i=1,j=1;
    int cnt=1;
    int ans=inf;
    b[v[1]]++;
    while(i<=j && j<=n)
    {
        if(cnt==m)
        {
            if(ans>j-i+1)
            {
                ans=j-i+1;
                p={i,j};
            }
            b[v[i]]--;
            if(b[v[i]]==0)  cnt--;
            i++;
        }
        else
        {
            j++;
            b[v[j]]++;
            if(b[v[j]]==1)  cnt++;
        }
    }
    cout<<p.first<<" "<<p.second;
}

  • 8
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值