如果对于任意的 a 1 ≤ a 2 < b 1 ≤ b 2 a1≤a2
a1≤a2<b1≤b2
有 m [ a 1 , b 1 ] + m [ a 2 , b 2 ] ≤ m [ a 1 , b 2 ] + m [ a 2 , b 1 ] m[a1,b1]+m[a2,b2]≤m[a1,b2]+m[a2,b1] m[a1,b1]+m[a2,b2]≤m[a1,b2]+m[a2,b1]
那么 m [ i , j ] m[i,j] m[i,j] 满足四边形不等式。
#include
using namespace std;
void show(){std::cerr << endl;}template<typename T,typename... Args>void show(T x,Args... args){std::cerr << "[ " << x << " ] , ";show(args...);}
typedef long long ll;
const int MAX = 4e3+50;
const int MOD = 1e9+7;
const int INF = 0x3f3f3f3f;
namespace Fast_IO{ ///orz laofu
const int MAXL((1 << 18) + 1);int iof, iotp;
char ioif[MAXL], *ioiS, *ioiT, ioof[MAXL],*iooS=ioof,*iooT=ioof+MAXL-1,ioc,iost[55];
char Getchar(){
if (ioiS == ioiT){
ioiS=ioif;ioiT=ioiS+fread(ioif,1,MAXL,stdin);return (ioiS == ioiT ? EOF : *ioiS++);
}else return (*ioiS++);
}
void Write(){fwrite(ioof,1,iooS-ioof,stdout);iooS=ioof;}
void Putchar(char x){*iooS++ = x;if (iooS == iooT)Write();}
inline int read(){
int x=0;for(iof=1,ioc=Getchar();(ioc<'0'||ioc>'9')&&ioc!=EOF;)iof=ioc=='-'?-1:1,ioc=Getchar();
if(ioc==EOF)exit(0);
for(x=0;ioc<='9'&&ioc>='0';ioc=Getchar())x=(x<<3)+(x<<1)+(ioc^48);return x*iof;
}
inline long long read_ll(){
long long x=0;for(iof=1,ioc=Getchar();(ioc<'0'||ioc>'9')&&ioc!=EOF;)iof=ioc=='-'?-1:1,ioc=Getchar();
if(ioc==EOF)exit(0);
for(x=0;ioc<='9'&&ioc>='0';ioc=Getchar())x=(x<<3)+(x<<1)+(ioc^48);return x*iof;
}
/**
#define lll __int128
inline lll read_lll(){
lll x=0;for(iof=1,ioc=Getchar();(ioc<'0'||ioc>'9')&&ioc!=EOF;)iof=ioc=='-'?-1:1,ioc=Getchar();
if(ioc==EOF)exit(0);
for(x=0;ioc<='9'&&ioc>='0';ioc=Getchar())x=(x<<3)+(x<<1)+(ioc^48);return x*iof;
}*/
template <class Int>void Print(Int x, char ch = '\0'){
if(!x)Putchar('0');if(x<0)Putchar('-'),x=-x;while(x)iost[++iotp]=x%10+'0',x/=10;
while(iotp)Putchar(iost[iotp--]);if (ch)Putchar(ch);
}
void Getstr(char *s, int &l){
for(ioc=Getchar();ioc==' '||ioc=='\n'||ioc=='\t';)ioc=Getchar();
if(ioc==EOF)exit(0);
for(l=0;!(ioc==' '||ioc=='\n'||ioc=='\t'||ioc==EOF);ioc=Getchar())s[l++]=ioc;s[l] = 0;
}
void Putstr(const char *s){for(int i=0,n=strlen(s);i<n;++i)Putchar(s[i]);}
} // namespace Fast_IO
using namespace Fast_IO;
int dp[MAX][805];
int pre[MAX][MAX];
int now_K;
int s(int L,int R){
return pre[R][R] - pre[L-1][R] - pre[R][L-1] + pre[L-1][L-1];
}
void solve(int L,int R,int qL,int qR){
if(L > R)return;
int mid = L + R >> 1;
int ID = qL;
int tmp = INF;
for(int i = qL;i <= qR && i <= mid;++i){
int val = s(i,mid) + dp[i-1][now_K-1];
if(val < tmp){
tmp = val;
ID = i;
}
}
dp[mid][now_K] = tmp;
solve(L,mid-1,qL,ID);
solve(mid+1,R,ID,qR);
}
int main()
{
int n,k;n = read();k = read();
for(int i = 0;i <= n;++i)
for(int j = 0;j <= k;++j)
dp[i][j] = INF;
dp[0][0] = 0;
for(int i = 1;i <= n;++i)
for(int j = 1;j <= n;++j){
int x = read();
pre[i][j] = x + pre[i-1][j] + pre[i][j-1] - pre[i-1][j-1];
}
for(int i = 1;i <= k;++i){
now_K = i;
solve(1,n,1,n);
}
int ans = dp[n][k] / 2;
cout << ans;
return 0;
}
/**
*/
'(',')','?'
三种-1
#include
using namespace std;
void show(){std::cerr << endl;}template<typename T,typename... Args>void show(T x,Args... args){std::cerr << "[ " << x << " ] , ";show(args...);}
typedef long long ll;
const int MAX = 5e4+50;
const int MOD = 1e9+7;
const int INF = 0x3f3f3f3f;
char ss[MAX];
int aa[MAX],bb[MAX];
struct node{
int val,pos;
bool operator < (const node &ND)const{
return val > ND.val;
}
};
priority_queue<node>Q;
char ans[MAX];
int main()
{
scanf("%s%*c",ss+1);
int n = strlen(ss+1);
int cnt = 0;
for(int i = 1;i <= n;++i){
if(ss[i] == '?')cnt++;
ans[i] = ss[i];
}
for(int i = 1;i <= cnt;++i){
scanf("%d%d",&aa[i],&bb[i]);
}
int pre = 0;
bool can = true;
ll fen = 0;
int ccnt = 0;
for(int i = 1;i <= n;++i){
if(ss[i] == '(')pre++;
else if(ss[i] == ')'){
pre--;
}else{
ccnt++;
ans[i] = ')';
fen += bb[ccnt];
Q.push((node){aa[ccnt] - bb[ccnt],i});
pre--;
}
// show(i,pre);
if(pre < 0){
if(Q.empty())can = false;
else{
fen += Q.top().val;
ans[Q.top().pos] = '(';
Q.pop();
pre+=2;
}
}
}
if(pre > 0)can = false;
if(!can)puts("-1");
else{
printf("%lld\n",fen);
printf("%s",ans+1);
}
return 0;
}
/**
*/
push
进优先队列中去,而不是 k k k 和 i i i 匹配更优的话我们就一定让 k k k 匹配掉了,因为有可能更后面的位置和 i i i 匹配了把 k k k 留下了。但暂时收益的话仍然是加进去的。#include
using namespace std;
void show(){std::cerr << endl;}template<typename T,typename... Args>void show(T x,Args... args){std::cerr << "[ " << x << " ] , ";show(args...);}
typedef long long ll;
const int MAX = 5e4+50;
const int MOD = 1e9+7;
const int INF = 0x3f3f3f3f;
struct node{
int val;
bool operator <(const node &ND)const{
return val < ND.val;
}
};
priority_queue<node>Q;
int main()
{
int n;scanf("%d",&n);
ll now = 0;
for(int i = 1;i <= n;++i){
int c;
scanf("%d",&c);
if(i == 1){
Q.push((node){-c});
}else{
int v = Q.top().val;
// show(i,c,v);
if(c + v > 0){
now += c + v;
Q.pop();
Q.push((node){-c}); // 可反悔贪心
}
Q.push((node){-c}); // 空着
}
// show(i,now);
}
cout << now;
return 0;
}
/**
*/
6,2,1,5,7,3,4
我们需要变成 x,2,1,x,x,3,7
(最大值放最后面,最小值不动),然后再调整成 5,2,1,4,6,3,7
,即其他每个位置都顺次低一位,这样他们之间的相对顺序不变。#include
#define IOS ios::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
using namespace std;
typedef long long ll;
void show(){std::cerr << endl;}template<typename T,typename... Args>void show(T x,Args... args){std::cerr << "[ " << x << " ] , ";show(args...);}
const int MAX = 1e5+50;
const int MOD = 1e9+7;
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
const double EPS = 1e-5;
ll qpow(ll a,ll n){/* */ll res = 1LL;while(n){if(n&1)res=res*a%MOD;a=a*a%MOD;n>>=1;}return res;}
ll qpow(ll a,ll n,ll p){a%=p;ll res = 1LL;while(n){if(n&1)res=res*a%p;a=a*a%p;n>>=1;}return res;}
ll npow(ll a,ll n){/* */ll res = 1LL;while(n){if(n&1)res=res*a;a=a*a;n>>=1;if(res<0||a<0)return 0;}return res;}
ll inv(ll a){/* */return qpow(a,MOD-2);}
ll inv(ll a,ll p){return qpow(a,p-2,p);}
int aa[MAX];
priority_queue<pair<int,int> >Q;
int main()
{
int n;cin >>n;
for(int i = 1;i <= n;++i){
cin >> aa[i];
}
int cnt = 0;
for(int i = 1;i <= n;++i){
for(int j = i+1;j <= n;++j){
if(aa[i] > aa[j]){
cnt++;
}
}
}
cout << cnt << '\n';
for(int i = n;i >= 2;--i){
for(int j = 1;j < i;++j){
if(aa[j] > aa[i]){
Q.push(make_pair(-aa[j],-j) );
}
}
while(!Q.empty()){
int p = -Q.top().second;
Q.pop();
cout << p << " " << i << '\n';
}
}
return 0;
}
/**
6 1 9 2 3 4 5
7
6 1 5 2 3 7 4
6
2 5 3 1 7 6
5 2 1 5 3 4
*/
-1
,否则输出一个构造解TL
飞起的。\random_shuffle
,然后选择前 20 20 20 个数字,即随机选择了 20 20 20 个数字wa200
了,运气感人。#include
#define IOS ios::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
using namespace std;
typedef long long ll;
void show(){std::cerr << endl;}template<typename T,typename... Args>void show(T x,Args... args){std::cerr << "[ " << x << " ] , ";show(args...);}
const int MAX = 2e5+50;
const int MOD = 1e9+7;
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
const double EPS = 1e-5;
ll qpow(ll a,ll n){/* */ll res = 1LL;while(n){if(n&1)res=res*a%MOD;a=a*a%MOD;n>>=1;}return res;}
ll qpow(ll a,ll n,ll p){a%=p;ll res = 1LL;while(n){if(n&1)res=res*a%p;a=a*a%p;n>>=1;}return res;}
ll npow(ll a,ll n){/* */ll res = 1LL;while(n){if(n&1)res=res*a;a=a*a;n>>=1;if(res<0||a<0)return 0;}return res;}
ll inv(ll a){/* */return qpow(a,MOD-2);}
ll inv(ll a,ll p){return qpow(a,p-2,p);}
ll aa[MAX];
map<ll,bool>M;
void check(ll x){
for(ll i = 2;i * i <= x;++i){
if(x % i == 0){
M[i] = 1;
while(x % i == 0){
x /= i;
}
}
}
if(x > 1)M[x] = 1;
}
int main()
{
int n;scanf("%d",&n);
for(int i = 1;i <= n;++i){
scanf("%lld",&aa[i]);
}
random_shuffle(aa+1,aa+1+n);
random_shuffle(aa+1,aa+1+n);
random_shuffle(aa+1,aa+1+n);
for(int i = 1;i <= min(20,n);++i){
ll now = aa[i];
if(now > 1){
check(now);
}
now = aa[i]+1;
if(now > 1){
check(now);
}
now = aa[i]-1;
if(now > 1){
check(now);
}
}
ll ans = n;
for(auto [a,b] : M){
ll tmp = 0;
for(int i = 1;i <= n;++i){
if(aa[i] <= a)
tmp += (a - aa[i]);
else
tmp += min(aa[i] % a,a - aa[i] % a);
if(tmp > ans)break;
}
ans = min(ans,tmp);
}
printf("%lld",ans);
return 0;
}
/**
*/
-1
判断很简单,若 a n a_n an 的 g c d > 1 gcd>1 gcd>1 肯定是无解的#include
#define IOS ios::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
using namespace std;
typedef long long ll;
void show(){std::cerr << endl;}template<typename T,typename... Args>void show(T x,Args... args){std::cerr << "[ " << x << " ] , ";show(args...);}
const int MAX = 3e5+50;
const int MOD = 1e9+7;
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
const double EPS = 1e-5;
ll qpow(ll a,ll n){/* */ll res = 1LL;while(n){if(n&1)res=res*a%MOD;a=a*a%MOD;n>>=1;}return res;}
ll qpow(ll a,ll n,ll p){a%=p;ll res = 1LL;while(n){if(n&1)res=res*a%p;a=a*a%p;n>>=1;}return res;}
ll npow(ll a,ll n){/* */ll res = 1LL;while(n){if(n&1)res=res*a;a=a*a;n>>=1;if(res<0||a<0)return 0;}return res;}
ll inv(ll a){/* */return qpow(a,MOD-2);}
ll inv(ll a,ll p){return qpow(a,p-2,p);}
ll fac[MAX],ivfac[MAX];
void init(int n){
fac[0] = 1;
for(int i = 1;i <= n;++i)fac[i] = fac[i-1] * i % MOD;
ivfac[n] = inv(fac[n]);
for(int i = n - 1;~i;--i)ivfac[i] = ivfac[i+1] * (i+1) % MOD;
}
ll C(int n,int m){
if(n < 0 || m > n)return 0;
return fac[n] * ivfac[m] % MOD * ivfac[n - m] % MOD;
}
bool vis[MAX];
int prime[MAX];
int mu[MAX];
int cnt;
void shai(int n){
mu[1] = 1;
for(int i = 2;i <= n;++i){
if(!vis[i]){
prime[++cnt] = i;
mu[i] = -1;
}
for(int j = 1;j <= cnt && i * prime[j] <= n;++j){
vis[i*prime[j]] = 1;
if(i % prime[j])mu[i*prime[j]] = -mu[i];
else {
mu[i*prime[j]] = 0;
break;
}
}
}
}
int barr[MAX];
ll F(int x,int shu){
return C(barr[x],shu);
}
int main()
{
shai(300000);
init(300000);
int n;scanf("%d",&n);
int gcd = 0;
for(int i = 1;i <= n;++i){
int x;scanf("%d",&x);
barr[x] = 1;
gcd = __gcd(gcd,x);
}
if(gcd > 1){
puts("-1");
return 0;
}
for(int i = 1;i <= 300000;++i)
for(int j = 2;i * j <= 300000;++j){
barr[i] += barr[i*j];
}
for(int i = 1;i <= 7;++i){
ll now = 0;
for(int j = 1;j <= 300000;++j){
now = (now + mu[j] * F(j,i) % MOD + MOD) % MOD;
}
// show(i,now);
if(now > 0){
printf("%d",i);
break;
}
}
return 0;
}
#include
#define IOS ios::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
using namespace std;
typedef long long ll;
void show(){std::cerr << endl;}template<typename T,typename... Args>void show(T x,Args... args){std::cerr << "[ " << x << " ] , ";show(args...);}
const int MAX = 5e3+50;
const int MOD = 998244353;
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
const double EPS = 1e-5;
ll qpow(ll a,ll n){/* */ll res = 1LL;while(n){if(n&1)res=res*a%MOD;a=a*a%MOD;n>>=1;}return res;}
ll qpow(ll a,ll n,ll p){a%=p;ll res = 1LL;while(n){if(n&1)res=res*a%p;a=a*a%p;n>>=1;}return res;}
ll npow(ll a,ll n){/* */ll res = 1LL;while(n){if(n&1)res=res*a;a=a*a;n>>=1;if(res<0||a<0)return 0;}return res;}
ll inv(ll a){/* */return qpow(a,MOD-2);}
ll inv(ll a,ll p){return qpow(a,p-2,p);}
int aa[MAX];
int lim[MAX];
ll f[MAX];
ll fac[MAX],ivfac[MAX];
void init(int n){
fac[0] = 1;
for(int i = 1;i <= n;++i)fac[i] = fac[i-1] * i % MOD;
ivfac[n] = inv(fac[n]);
for(int i = n - 1;~i;--i)ivfac[i] = ivfac[i+1] * (i+1) % MOD;
}
ll A(int n,int m){
if(n < 0 || m > n)return 0;
return fac[n] * ivfac[n-m] % MOD;
}
int main()
{
init(5000);
int n;cin >>n;
for(int i = 1;i <= n;++i)cin >>aa[i];
sort(aa+1,aa+1+n);
if(2*aa[n-1] > aa[n]){
puts("0");
return 0;
}
for(int i = 1;i <= n;++i){
for(int j = 1;j < i;++j){
if(2*aa[j] <= aa[i]){
lim[i] = j;
}else{
break;
}
}
}
f[0] = 1;
lim[0] = -1;
for(int i = 1;i <= n;++i){
for(int j = 0;j <= lim[i];++j){
f[i] = (f[i] + f[j] * A(n - lim[j] - 2,lim[i] - lim[j] - 1) % MOD) % MOD;
}
}
cout << f[n];
return 0;
}
/**
*/