# cf #572 div2 my solution

### A

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

const int maxn = 2e5+10;
const int mod = 1e9+7;

int solve(string s)
{
int num=0;
for(int i=0;i<s.length();++i){
if(s[i]=='1') num++;
}
return num;
}

int main()
{
int n;
cin>>n;
string s;
cin>>s;
if(solve(s) != n - solve(s)){
cout<<1<<endl;
cout<<s<<endl;
}
else{
cout<<2<<endl;
cout<<s[0]<<" "<<s.substr(1)<<endl;
}
return 0;
}


### B

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

const int maxn = 1e5+10;

int a[maxn];

int main()
{
int n;
cin>>n;
for(int i=0;i<n;++i) cin>>a[i];
sort(a,a+n);
if(a[n-1]>=a[n-2]+a[n-3]){
cout<<"NO"<<endl;
}
else{
cout<<"YES"<<endl;
cout<<a[n-3]<<" "<<a[n-1]<<" "<<a[n-2];
for(int i=n-4;i>=0;--i) cout<<" "<<a[i];
cout<<endl;
}
return 0;
}


### C

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

const int maxn = 1e5+10;
const int duan = 32*(1<<1)-(1<<5);
int n;
int a[maxn];
int pre[maxn];

void init()
{
pre[1] = a[1];
for(int i=2;i<=n;++i) pre[i] = pre[i-1] + a[i];
}

int main()
{
ios::sync_with_stdio(false);
cin>>n;
for(int i=1;i<=n;++i){
cin>>a[i];
}
init();
int q;
cin>>q;
while(q--)
{
int l,r;
cin>>l>>r;
cout<<(pre[r] - pre[l-1] )/10<<endl;
//cout<<l<<" "<<r<<endl;
}
return 0;
}



### D1

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

const int maxn = 1e5+10;

int n;
int du[maxn];

int main()
{
ios::sync_with_stdio(false);
cin>>n;
int nn=n;
int a,b;
n--;
while(n--)
{
cin>>a>>b;
du[a]++;
du[b]++;
}
bool flag=0;
for(int i=1;i<=nn;++i){
if(du[i]==2){
cout<<"NO"<<endl;
return 0;
}
}
cout<<"YES"<<endl;
return 0;
}



### D2

1. v是另外一个叶子节点,显然满足

2. v不是叶子节点,则其度数一定>2,(2不可能,因为直接令相关的两条边权值不同,就构造不了)

由于其度数>2,则至少对应3颗子树. 我们分别找三颗子树中的三个叶子,记为$l_1, l_2, u$.

则对$u->l_1$ 加上$x/2$ , 对$u->l_2$加上$x/2$, $l_1-> l_2$减去$x/2$ ,

最后相当于对$u->v$ 加上了$x$ . #

solve(v):

if $v$ doesn’t have sons, then return.

otherwise, for each son $u$ we wiil find a leaf in subtree of $u$ — let’s name it $w$. Than, add $a_{uv}$ on the path
$vw$ and recalculate needed numbers on the edge in this path(it means for each edge $e$ on the path make this $a_e -= a_{uv}$),
after it, call solve($u$).

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

const int maxn = 1e3+10;

int a[maxn],root;// fa[root] = 0
pair<int,int> b[maxn];//two leaf for every node
vector<pair<int,int>> G[maxn];

void dfs(int u, int fa){
if(G[u].size()==1 && fa){// leaf  返回自己的编号
b[u].first = u;//自己指向自己
b[u].second = -1;//标记
return ;
}
for(int i=0;i<G[u].size();++i){
int v = G[u][i].first;
if(v == fa) continue;
dfs(v, u);
if(!b[u].first) b[u].first = b[v].first;
else if(!b[u].second) b[u].second = b[v].first;
}
}

void dfs2(int u, int fa){
if(G[u].size()==1) return ;
for(int i=0;i<G[u].size();++i){
if(G[u][i].first == fa) continue;
int v = G[u][i].first;
int val = G[u][i].second;
//u->v val
int l1 = b[u].first;
int l2 = b[u].second;
assert(l1!=l2);
if(b[v].first == l1 || b[v].first == l2){
//将l1 或 l2换掉
if(u == root){//如果是根至少有三个值 一定能找到
for(int j=0;j<G[u].size();++j){
if(b[G[u][j].first].first!= l1 && b[G[u][j].first].first!=l2){
if(b[v].first == l1) l1 = b[G[u][j].first].first;
if(b[v].first == l2) l2 = b[G[u][j].first].first;
break;
}
}
}
else{//u不是根 则fa一定有另一个兄弟 取他的叶子
for(int j=0;j<G[fa].size();++j){
if(G[fa][j].first ==u ) continue;
if(b[G[fa][j].first].first != l1 && b[G[fa][j].first].first != l2){
if(b[v].first == l1) l1 = b[G[fa][j].first].first;
if(b[v].first == l2) l2 = b[G[fa][j].first].first;
break;
}
if(b[G[fa][j].first].second != l1 && b[G[fa][j].first].second != l2){
if(b[v].first == l1) l1 = b[G[fa][j].first].second;
if(b[v].first == l2) l2 = b[G[fa][j].first].second;
break;
}
}
}
}
cout<<b[v].first<<" "<<l1<<" "<<val/2<<endl;
cout<<b[v].first<<" "<<l2<<" "<<val/2<<endl;
cout<<l1<<" "<<l2<<" "<<-val/2<<endl;
//v 不是叶子
if(G[v].size()!=1){
//取 l1 b[v].first  和 b[v].second
cout<<b[v].first<<" "<<l1<<" "<<-val/2<<endl;
cout<<b[v].first<<" "<<b[v].second<<" "<<-val/2<<endl;
cout<<l1<<" "<<b[v].second<<" "<<val/2<<endl;
}
dfs2(v,u);
}
}

int main()
{
//freopen("in.txt","r",stdin);
ios::sync_with_stdio(false);
int n,leanum=0;
cin>>n;
for(int i=0;i<n-1;++i){
int u,v,val;
cin>>u>>v>>val;
G[u].push_back(make_pair(v,val));
G[v].push_back(make_pair(u,val));
}
for(int i=1;i<=n;++i) if(G[i].size()==2) {
cout<<"NO"<<endl;
return 0;
}
if(n==2){
cout<<"YES"<<endl;
cout<<"1"<<endl;
cout<<"1 2 "<<G[1][0].second<<endl;
return 0;
}
//找一个du>1的node作为根
for(int i=1;i<=n;++i) if(G[i].size()>2){root = i ;break;}
dfs(root, 0);
//for(int i=1;i<=n;++i) cout<<b[i].first<<" "<<b[i].second<<endl;
for(int i=1;i<=n;++i) if(G[i].size()==1) leanum++;
cout<<"YES"<<endl;
cout<<6*(n-1) - 3*leanum<<endl;
dfs2(root, 0);
return 0;
}


### E

find how many pairs satisfy below :
$(a_i + a_j)(a_i^2 + a_j^2) \equiv k \bmod p$

$a_i^4 - a_j^4 \equiv k*(a_i - a_j)$

$a_i^4 - k*a_i \equiv a_j^4 - k*a_j \quad mod \ p$

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

const int maxn = 3e5+10;

int n,k,p;

int a[maxn];
unordered_map<int, int> mp;
int main()
{
ios::sync_with_stdio(false);
cin>>n>>p>>k;
for(int i=0;i<n;++i){
long long t;
cin>>t;
a[i] = t*t%p*t%p*t%p;
a[i] = ((a[i] - k*t)%p + p)%p;
}
long long ans=0;
for(int i=0;i<n;++i){
int t = mp[a[i]];
ans+=t;
mp[a[i]] = t+1;
}
cout<<ans<<endl;
return 0;
}


### F

1. 如何求$p_i$

$dp[i][j]$ 表示以第$i$个数结尾,长度为$j$ 且满足价值至少为$limit$ 的序列数量.

转移: 从$dp[j-1,j,...i-1][j-1]$ 转移过来 第一感觉时间复杂度$O(n^2 k )$

考虑对原数组排序,不影响答案.(原先要任意挑出一对 , 排序前 排序后看成双射即可)

如果数组是有序的,对于$dp[..i-1,i,i+1..][j]$ 他们的转移有公共部分.

具体来说,是单调的 所以对同一列的$dp$值,可以维护一个now指针,表示最靠右的数 且满足$a[now]+limit<=a[i]$

当i+1了,再尽量让now变大 , 时间复杂度为$O(nk)$

2. 时间复杂度

再加上一开始的Limit的枚举,复杂度为$O(max(a)*n*k)$

考虑真的要$dp$ $max(a)$ 次吗?

假设当前$limit = x$, 则从$a[1]$$a[k]$ 至少增加了$(k-1)*x$ 而对于数组$a$ ,提供的最大增量为$a[n]-a[1]$ (排序后). 因此只要对$(k-1) *x \leq a[n] - a[1]$的那些$x$ ,求$p_x$ 而更大的$x$ ,显然$p_x = 0$ .

时间复杂度为$O({max(a) \over (k-1)} * nk) = O(max(a) * n)$ 可以跑完.

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int k,n;
const int maxn = 1e3+10;
const int mod = 998244353;
int a[maxn];
int dp[maxn][maxn];//dp[i][len] 以第i个数结尾 长度为len的序列 （且满足价值最小比某个下界大于等于）的数量

int solve(int limit)
{
for(int j=2;j<=k;++j){//后面每一列
int now_v = 0, now_i = j-2;
for(int i=j;i<=n;++i){
while( a[now_i+1]+limit<=a[i]  && now_i+1 < i){//先维护now_i 看最右能到哪
now_i++;
now_v=now_v + dp[now_i][j-1];
if(now_v > mod) now_v-=mod;
}
dp[i][j]=now_v;
}
}
int ans = 0;
for(int i=k;i<=n;++i) ans = (ans + dp[i][k] >= mod) ? ans+dp[i][k] - mod : ans + dp[i][k];
return ans;
}

int main()
{
//freopen("in.txt","r",stdin);
ios::sync_with_stdio(false);
cin>>n>>k;
for(int i=1;i<=n;++i) cin>>a[i];
sort(a+1,a+1+n);
int ans = 0;
for(int i=1;i<=n;++i) dp[i][1] = 1;    //第一列
for(int i=1;i<=(a[n] - a[1])/(k-1);++i) ans = (ans + solve(i))%mod;
cout<<ans<<endl;
return 0;
}