标签:char ++ for size open [1] void 相等 ext
问有几个无序二元组 $ (x ?, ?y) $ 满足 $ xy \equiv 1?(mod?P ) $ , $ 0 \leq x < P?, ?0 \leq y <P $
你没看错,这是day1的T1,一道赤裸裸的数学题。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
#define N 50000005
#define M 1000005
using namespace std;
int n,prime[M];
int num,phi[N];
bool flag[N];
inline void open_judge() {
freopen("count.in","r",stdin);
freopen("count.out","w",stdout);
}
int main() {
open_judge();
scanf("%d",&n);
flag[1] = 1;
phi[1] = 1;
for(int i = 2 ; i <= n ; i++) {
if(!flag[i]) {
prime[++num] = i;
phi[i] = i - 1;
}
for(int j = 1 ; j <= num && prime[j] * i <= n ; j++) {
flag[prime[j] * i] = 1;
if(i % prime[j] == 0) {
phi[i * prime[j]] = phi[i] * prime[j];
break;
}
phi[i * prime[j]] = phi[i] * phi[prime[j]];
}
}
for(long long i = 1 ; i <= n ; i++)
if(i * i % n == 1) phi[n]++;
printf("%d\n",phi[n] / 2);
return 0;
}
给出平面上 n 个点,你要把每个点染成黑色或白色。要求染完之后,任意一条与坐标轴平行的直线上,黑白点数量差的绝对值小于等于 1。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct Data {
int v;
int p;
}data[500005];
struct Edge {
int to;
int next;
}e[1000005];
int n,m,cnt=1,head[1000005],d[1000005];
int x[500005],y[500005],num,ans[500005];
bool flag[500005];
void add_edge(int u,int v) {
e[++cnt].to = v;
e[cnt].next = head[u];
head[u] = cnt;
}
inline bool cmp(Data a,Data b) {
return a.v < b.v;
}
void lisan() {
for(int i = 1 ; i <= n ; i++) {
data[i].p = i;
data[i].v = x[i];
}
sort(data+1,data+n+1,cmp);
data[0].v=-1;
for(int i = 1 ; i <= n ; i++) {
if(data[i].v != data[i-1].v) num++;
x[data[i].p] = num;
}
for(int i = 1 ; i <= n ; i++) {
data[i].p = i;
data[i].v = y[i];
}
sort(data+1,data+n+1,cmp);
data[0].v = -1;
for(int i = 1 ; i <= n ; i++) {
if(data[i].v != data[i-1].v) num++;
y[data[i].p] = num;
}
}
void dfs(int node,bool last) {
while(1) {
bool ff = 1;
for(int&hd = head[node] ; hd ; hd = e[hd].next) {
if(flag[hd>>1]) continue;
flag[hd>>1] = 1;
d[node]--;
d[e[hd].to]--;
ans[hd>>1] = !last;
node = e[hd].to;
last = !last;
ff = 0;
break;
}
if(ff) break;
}
}
inline int read() {
char c=getchar();
int t=0;
while(c>'9'||c<'0')c=getchar();
while(c>='0'&&c<='9') {t=t*10+c-'0';c=getchar();}
return t;
}
inline void open_judge() {
freopen("color.in","r",stdin);
freopen("color.out","w",stdout);
}
int main() {
open_judge();
n = read();
for(int i = 1 ; i <= n ; i++) {
x[i] = read();
y[i] = read();
}
lisan();
for(int i = 1 ; i <= n ; i++) {
d[x[i]]++,d[y[i]]++;
add_edge(x[i],y[i]);
add_edge(y[i],x[i]);
}
for(int i = 1 ; i <= num ; i++) {
if(d[i] & 1) {
d[i]++,d[num+1]++;
add_edge(i , num + 1);
add_edge(num + 1 , i);
}
}
num++;
memset(ans,-1,sizeof(ans));
for(int i = 1 ; i <= num ; i++) {
while(d[i]) dfs(i,0);
}
for(int i = 1 ; i <= n ; i++)
printf("%d ",ans[i]);
printf("\n");
return 0;
}
给出一个 $ n (n \leq 5 \times 10^5) $ 个数的序列,一个区间的价值是区间内最小值乘最大值的积。求所有区间价值和,答案对 $ 998244353 $ 取模。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define ll long long
#define MOD 998244353
#define N 500005
using namespace std;
ll n,a[N],ans,maxl[N];
ll maxr[N],minl[N],minr[N];
ll sum[N],sum_minl[N],sum_maxl[N];
void work(int l,int r) {
if(l > r)return;
if(l == r) {
ans = (ans + a[l] * a[r]) % MOD;
return;
}
int mid = (l+r) >> 1;
work(l , mid - 1);
work(mid + 1 , r);
ll s = 0;
maxl[0] = maxr[0] = minl[0] = minr[0] = a[mid];
for(int i = mid + 1 ; i <= r ; i++) {
maxr[i - mid] = max(maxr[i - mid - 1] , a[i]);
minr[i - mid] = min(minr[i - mid - 1] , a[i]);
}
for(int i = mid - 1 ; i >= l ; i--) {
maxl[mid - i] = max(maxl[mid - i - 1] , a[i]);
minl[mid - i] = min(minl[mid - i - 1] , a[i]);
}
sum[mid - l + 1] = 0;
for(int i = l ; i <= mid ; i++) {
sum[mid - i] = (sum[mid - i + 1] + minl[mid - i] * maxl[mid - i]) % MOD;
sum_minl[mid - i] = (sum_minl[mid - i + 1] + minl[mid - i]) % MOD;
sum_maxl[mid - i] = (sum_maxl[mid - i + 1] + maxl[mid - i]) % MOD;
}
int now_minl = 0 , now_maxl = 0;
for(int i = 0 ; i <= r - mid ; i++) {
while(now_minl <= mid - l && minl[now_minl] >= minr[i]) now_minl++;
while(now_maxl <= mid - l && maxl[now_maxl] <= maxr[i]) now_maxl++;
ans = (ans + minr[i] * maxr[i] % MOD * min(now_minl , now_maxl)) % MOD;
ans = ans + sum[max(now_minl , now_maxl)];
if(now_minl < now_maxl)
ans = (ans + (sum_minl[now_minl] - sum_minl[now_maxl] + MOD) * maxr[i]) % MOD;
else ans = (ans + (sum_maxl[now_maxl] - sum_maxl[now_minl] + MOD) * minr[i]) % MOD;
}
}
inline void open_judge() {
freopen("sequence.in","r",stdin);
freopen("sequence.out","w",stdout);
}
int main() {
open_judge();
scanf("%lld",&n);
for(int i = 1 ; i <= n ; i++)
scanf("%lld",&a[i]);
work(1,n);
printf("%lld\n" , ans % MOD);
return 0;
}
标签:char ++ for size open [1] void 相等 ext
原文地址:https://www.cnblogs.com/Repulser/p/9891004.html