每個字母分開考慮,一定至少有乙個字母不動,列舉不動的位置,向兩側擴充套件至最大,嘗試更新答案
注意無窮大的選擇
code
#include #include using namespace std;
int sum[27][4005],cnt[27];
char c[4005];
int main()
int ans=0;
for(int i=1;i<=26;++i)
if(p2<=cnt[i]&&dis>sum[i][p2]-sum[i][j]-r)
if(dis>res)break;
res-=dis;++ls;
if(netls?ans:ls;}}
printf("%d\n",ans);
return 0;
}
\(a=p^2*x\)
\(b=q^2*y\)
(\(x,y\)不含平方因子)
若\(a*b\)為平方數,那麼有
\(x*y\)為平方數,即\(x==y\)
將每個數的平方因子去掉,剩餘部分判斷有多少相等的,統計答案,可以使用排序
怎麼去掉平方因子
暴力:直接列舉平方數->tle
接近正解的優雅暴力: 篩質數,每次嘗試去掉質數平方因子,大大減少列舉量,像我一樣寫的優雅些會有90pts ->tle
發現瓶頸在於列舉量上,考慮減少列舉的質數
我們只篩出來\(1-\sqrt[3]\)的質數進行列舉,將只有乙個的質因子也去掉,(記下來)
考慮乙個數能寫成\(p^2*x\)的形式,其中\(p>\sqrt[3]\),那麼有\(x<\sqrt[3]\)
所以最後再判斷一下這個數是不是平方數,然後把去掉的單個因子乘回來
code
#include #include #include #includeusing namespace std;
const int maxn=300005;
int a[maxn];
bool flag[40005];
int prime[20005],cnt;
void prim()
}}int main()
}int p=round(sqrt(a[i]));
if(a[i]==p*p)a[i]=1;
a[i]*=num;
}sort(a+1,a+n+1);
long long ans=0;
int las=a[1],num=1;
for(int p=2;p<=n+1;++p)
++num;
}printf("%lld\n",ans);
return 0;
}
組合+容斥,組合結合dp可以水到75pts
考慮到了正解需要容斥,但是過於複雜,寫不出來,題解的分步容斥真的是太妙了
不考慮壞點從a到b的路徑數\(\pi_^ c_^\)(\(sum\)為剩餘的總距離差)
設\(path(x,y)\)表示\(x\)到\(y\)的路徑數
乙個壞點\(x\),不合法的路徑數為\(path(a,x)*path(x,b)\)
多個壞點,不合法路徑數為單個壞點不合法路徑+通過兩個壞點的路徑書-通過三個...................
發現這樣很難寫,而且複雜度極高
換一種思路,無論哪種不合法路徑,一定經過乙個壞點,如果我們知道到達壞點\(i\),且不經過其他壞點的路徑數,那麼答案就好求了
設\(f[i]\)為到達壞點\(i\)的,不經過其他壞點的方案數
有\(f[i]=path(a,i)-\sum path(j,i)*f[j]\)
\((j\)的所有座標都小於\(i)\)
那麼我們需要預先對點進行排序,以確定列舉順序,我使用了所有座標的和進行排序,(因為瞎調所以多寫了幾個沒用的取模,請自動忽略)
最後答案為\(path(a,b)-\sum_^ f[i]*path(i,b)\)
code#include #include #include using namespace std;
const int mod=1e9+7;
const int maxn=5000000;
struct zbh[505];
bool cmp(zb x,zb y)
return ans;
}long long get_c(int n,int m)
void ycl()
long long path(zb &x)
return ans%mod;
}long long get_path(int x,int y)
bool check(int x,int y)
void ts()
void work()
struct edge;
struct node;
struct g
void pre_work()
}g1,g2;
int rem[maxn],n,m,dl[maxn],dr[maxn],a[maxn];
void in()
}void tp()
}for(int i=1;i<=n;++i)rem[i]=g2.rd[i];
for(int i=1;i<=n;++i)if(!rem[i])q.push(i);
while(!q.empty())
}for(int i=1;i<=g1.tot;++i)g1.e[i].val=dl[g1.e[i].from]+dr[g1.e[i].to]+1;
for(int i=1;i<=g2.tot;++i)g2.e[i].val=dr[g2.e[i].from]+dl[g2.e[i].to]+1;
}struct tree
void add(int x,int l,int r,int k)
int mid=(l+r)>>1;
if(k<=mid)
if(k>mid)
++t[x].val;
}void del(int x,int l,int r,int k)
int mid=(l+r)>>1;
if(k<=mid)del(t[x].l,l,mid,k);
if(k>mid)del(t[x].r,mid+1,r,k);
--t[x].val;
}int query(int x,int l,int r)
}t;void ga(){
int root=++t.cnt;
for(int i=1;i<=n;++i)t.add(root,0,n,dr[i]);
int city,ans=inf;
for(int k=1;k<=n;++k){
int i=a[k];
for(int j=g2.head[i];j;j=g2.e[j].net)t.del(root,0,n,g2.e[j].val);
t.del(root,0,n,dr[i]);
int ls=t.query(root,0,n);
if(ls
NOIP提高組五校聯考 string
給出乙個長度為n,由小寫英文本母組成的字串s,求在所有由小寫英文本母組成且長度為n 且恰好有k 位與s 不同的字串中,給定字串t 按照字典序排在第幾位。由於答案可能很大,模10 9 7 輸出。列舉乙個 i 表示當前做到第 i位,而前i 1 位的字元都已經與目標串的前i 1 位相同,那麼對於當前位置可...
NOIP2016提高A組五校聯考1 道路規劃
我們考慮,當現在有乙個合法的集合時,如何往裡面增加乙個點,使這個集合仍然合法。假設現在有乙個合法的集合,那麼當我們加入乙個點,它的道路穿過來整個集合,那麼 然後搞一遍最長下降子串行就可以了。include include include include include const int maxlo...
NOIP2016提高A組五校聯考1 挖金礦
剛看到這題時,還在想怎麼貪心,然後很快的打完之後發現貪心是錯的。然後仔細的看了看範圍,哈哈,這不是二分嗎。二分出乙個mid,然後在所有行裡面用mid j 字首和然後找乙個最大值。最後把這些最大值加起來,判斷一下就好了。include include include include include i...