感觉这场还是挺简单的(但这并不影响我仍然不会做QwQ
E E E题感觉啥都想到了。…知道要去求最短路…但却没有想到dij…???(smg
肯定是尽量改 [ 2 , n − 1 ] [2,n-1] [2,n−1]的嘛…所以你就一遍扫下来就行啦呀
#include
#define ll long long
using namespace std;
const int N = 1e5 + 10;
ll a[N];
int main() {
int n, x;
cin >> n >> x;
for(int i = 1; i <= n; ++i) {
scanf("%lld", &a[i]);
}
ll pos = 0;
for(int i = 2; i <= n; ++i) {
ll gg = max(0ll, (a[i] + a[i - 1]) - x);
a[i] -= min(a[i], gg);
pos += gg;
}
printf("%lld\n", pos);
return 0;
}
可以发现
如果头和尾是相同的话 假设这么一个串 a b a b a ababa ababa( b b b可以为任意字符)
那么长度为奇数的话必败
如果头和尾不相同 那么这么一个串 a c a c acac acac( a , c a,c a,c也可以为任意字符)
那么长度为偶数的话必败
#include
using namespace std;
const int N = 1e5 + 10;
char lx[N];
int main() {
scanf("%s", lx + 1);
int len = strlen(lx + 1);
if(lx[1] == lx[len]) {
if(len & 1) printf("Second\n");
else printf("First\n");
} else {
if(len & 1) printf("First\n");
else printf("Second\n");
}
return 0;
}
把每一个圆当作一个点 (圆和圆之间的距离是圆心距离-半径和 和 0 0 0取个max就行啦)
然后你跑一遍最短路就行了
#include
using namespace std;
const int N = 1010;
const double inf = 1e-12;
struct Point {
double x, y;
} c[N];
int vis[N];
double R[N], f[N];
double pf(double x) {
return x * x;
}
double dis(Point A, Point B) {
return sqrt(pf(A.x - B.x) + pf(A.y - B.y));
}
double get(int k, int j) {
return max(0.0, dis(c[k], c[j]) - (R[k] + R[j]));
}
int main() {
for(int i = 1; i <= 2; ++i) {
scanf("%lf%lf", &c[i].x, &c[i].y);
R[i] = 0;
}
int n;
scanf("%d", &n);
n += 2;
for(int i = 1; i <= n; ++i) f[i] = 3e9;
for(int i = 3; i <= n; ++i) {
scanf("%lf%lf%lf", &c[i].x, &c[i].y, &R[i]);
}
f[1] = 0;
for(;;) {
int be = -1;
for(int i = 1; i <= n; ++i) {
if(vis[i]) continue;
if(be == -1 || f[be] > f[i]) be = i;
}
if(be == -1) break;
vis[be] = 1;
for(int i = 1; i <= n; ++i) {
f[i] = min(f[i], f[be] + get(i, be));
}
}
printf("%.12f\n", f[2]);
return 0;
}
我们设 f [ i ] f[i] f[i]表示长度为 i i i且没有长度大于1的循环节的回文串个数
那么显然 f [ i ] = k ⌈ i 2 ⌉ − ∑ d ∣ i f [ d ] f[i]=k^{\lceil{\dfrac{i}{2}}\rceil}-\sum_{d|i}f[d] f[i]=k⌈2i⌉−∑d∣if[d]
由于每次你只需要根号级别复杂度…所以这个可以很快处理出来
那么最后的 a n s = ∑ d ∣ n [ d & 1 ] ∗ d ∗ f [ d ] + [ ! ( d & 1 ) ] ∗ d 2 ∗ f [ d ] ans=\sum_{d|n}[d\&1]*d*f[d]+[!(d\&1)]*\dfrac{d}{2}*f[d] ans=∑d∣n[d&1]∗d∗f[d]+[!(d&1)]∗2d∗f[d]
因为长度为偶数时 移到一半的时候就会开始重复 所以要除以2
#include
#define ll long long
using namespace std;
const int mod = 1e9 + 7;
int n, k;
map<int, ll> f;
ll add(ll x, ll y) {
return (x + y + mod) % mod;
}
void Add(ll &x, ll y) {
x = (x + y + mod) % mod;
}
ll mul(ll x, ll y) {
return (x * y) % mod;
}
void Mul(ll &x, ll y) {
x = (x * y) % mod;
}
ll q_pow(ll x, int y) {
ll ans = 1;
for(; y; y >>= 1) {
if(y & 1) Mul(ans, x);
Mul(x, x);
}
return ans;
}
ll get(int x) {
if(!f.count(x)) {
int len = sqrt(x);
ll pos = q_pow(k, (x / 2) + (x & 1));
for(int i = 2; i <= len; ++i) {
if(x % i) continue;
Add(pos, -get(i));
if(i * i != x) Add(pos, -get(x / i));
}
if(x != 1) Add(pos, -k);
return f[x] = pos;
} else return f[x];
}
int main() {
scanf("%d%d", &n, &k);
int len = sqrt(n);
ll ans = 0;
for(int i = 1; i <= len; ++i) {
if(n % i) continue;
if(i & 1) Add(ans, mul(i, get(i)));
else Add(ans, mul(i / 2, get(i)));
if(i * i != n) {
int now = n / i;
if(now & 1) Add(ans, mul(now, get(now)));
else Add(ans, mul(now / 2, get(now)));
}
}
printf("%lld\n", (ans + mod) % mod);
return 0;
}
本文作者:Averyta
博客地址:https://blog.csdn.net/AngryVegetable