容斥原理
#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
typedef long long ll;
const int maxn = 1e6 + 5;
ll a[25];
int k;
ll solve(ll x)
{
ll ans = x;
for(int i = 1;i < (1<<k);i ++)
{
ll tmp = x;
int flag = 1;
for(int j = 0;j < k;j ++)
{
if(i&(1<<j))
{
tmp /= a[j];
flag *= -1;
}
}
ans += tmp*flag;
}
return ans;
}
int main()
{
ll l, r;
cin >> l >> r >> k;
for(int i = 0;i < k;i ++)
cin >> a[i];
printf("%lld\n",solve(r)-solve(l-1));
return 0;
}
从1到n遍历 i每能除一次5 就加一次 直到 i / 5 为0 再继续下一个数
原理就是尾0需要有5与其他数字 比如 2 4等相乘结果得出 反求个数的话就除5
#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
typedef long long ll;
const int maxn = 1e6 + 5;
ll ans,t,n;
int main()
{
cin >> n;
for(int i = 1;i <= n;i ++)
{
ll tmp = i;
while(tmp%5==0)
{
t ++;
tmp /= 5;
}
ans += t;
}
cout << ans;
return 0;
}
直接套公式
n * (n - 1) / 2 + n * (n- 1) * (n - 2) * (n - 3) / 24 + 1
#include <cstdio>
using namespace std;
long long n,ans;
int main()
{
while(scanf("%lld",&n)==1)
{
ans=1 + n*(n-1)/2 + n*(n-1)*(n-2)*(n-3)/24;
printf("%lld\n",ans);
}
return 0;
}
看着题比较复杂 实际上很见到
看它给的例子可以发现是个斐波那契 ,不过与这个无关 ,写下去就是每隔两天之后第三天就不能吃
所以 每3天里有2天可以,1天不可以
#include<bits/stdc++.h>
using namespace std;
int main()
{
long long n;
while(scanf("%lld",&n) != EOF)
{
long long t = n-n/3;
cout << t << endl;
}
}
签到 ,需要注意的数字范围, 需要用一个数先除以gcd 然后再乘以另一个数字 不然会爆掉
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b)
{
return b == 0 ? a : gcd(b, a % b);
}
int main()
{
ll a, b;
cin >> a >> b;
cout << a / gcd(a,b) * b;
return 0;
}
其实开始用树状数组板子交了一发。。也过了
看了一下他们用的是差分数组做的
贴两组代码把
先是差分数组:
#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
typedef long long ll;
const int maxn = 1e6 + 5;
ll a[maxn],b[maxn];
int n, m, l, r;
int main()
{
cin >> n >> m;
for(int i = 1;i <= n;i ++)
{
scanf("%d",&a[i]);
}
int q, tl, tr, p;
for(int i = 1;i <= m;i ++)
{
scanf("%d%d%d%d",&q,&tl,&tr,&p);
if(q == 1)
p = -p;
b[tl] += p;
b[tr + 1] -= p;
}
for(int i = 1;i <= n;i ++)
{
b[i] += b[i-1];
a[i] += b[i] + a[i - 1];
}
cin >> l >> r;
cout << a[r] - a[l-1] << endl;
return 0;
}
然后是树状数组:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e6+5;
long long c[maxn] = {0}, n, m;
int lowbit(int t)
{
return t&(-t);
}
void add(int k, int t)
{
while(k <= n)
{
c[k] += t;
k += lowbit(k);
}
}
int sum(int k)
{
int ans = 0;
while(k > 0)
{
ans += c[k];
k -= lowbit(k);
}
return ans;
}
int main()
{
int x, l, r, tmp;
scanf("%lld%lld", &n, &m);
for(int i = 1;i <= n;i ++)
{
scanf("%d", &x);
add(i, x);
add(i + 1, -x);
}
while(m --)
{
scanf("%d%d%d%d", &tmp, &l, &r, &x);
if(tmp == 1)
x = -x;
add(l, x);
add(r + 1, -x);
}
long long s = 0;
scanf("%d%d", &l, &r);
for(int i = l;i <= r;i ++)
s += sum(i);
cout << s << endl;
return 0;
}
暴力模拟
#include <iostream>
#include <stdio.h>
using namespace std;
bool isReverse(int a, int b)
{
return (a / 10 == b % 10 && a % 10 == b / 10);
}
int main()
{
int x, y, a, b;
scanf("%d:%d", &x, &y);
//find last time
a = x; b = y;
do
{
b--;
if (b < 0)
{
b = 59;
a = (a - 1 + 24) % 24;
}
} while (!isReverse(a, b));
printf("%d:%d\n", a, b);
//find next time
a = x; b = y;
do
{
b++;
if (b > 59)
{
b = 0;
a = (a + 1) % 24;
}
} while (!isReverse(a, b));
printf("%d:%d\n", a, b);
return 0;
}